Implement basic kerning when rendering text.
Only old-style `kern` tables are supported--modern GPOS-based kerning is not supported.pull/1224/merge
parent
cc64fed2d0
commit
40a1fdc6af
|
@ -19,6 +19,17 @@ void TextWindow::ScreenEditTtfText(int link, uint32_t v) {
|
||||||
SS.TW.edit.request = hr;
|
SS.TW.edit.request = hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextWindow::ScreenToggleTtfKerning(int link, uint32_t v) {
|
||||||
|
hRequest hr = { v };
|
||||||
|
Request *r = SK.GetRequest(hr);
|
||||||
|
|
||||||
|
SS.UndoRemember();
|
||||||
|
r->extraPoints = !r->extraPoints;
|
||||||
|
|
||||||
|
SS.MarkGroupDirty(r->group);
|
||||||
|
SS.ScheduleShowTW();
|
||||||
|
}
|
||||||
|
|
||||||
void TextWindow::ScreenSetTtfFont(int link, uint32_t v) {
|
void TextWindow::ScreenSetTtfFont(int link, uint32_t v) {
|
||||||
int i = (int)v;
|
int i = (int)v;
|
||||||
if(i < 0) return;
|
if(i < 0) return;
|
||||||
|
@ -205,8 +216,11 @@ void TextWindow::DescribeSelection() {
|
||||||
Printf(false, "%FtTRUETYPE FONT TEXT%E");
|
Printf(false, "%FtTRUETYPE FONT TEXT%E");
|
||||||
Printf(true, " font = '%Fi%s%E'", e->font.c_str());
|
Printf(true, " font = '%Fi%s%E'", e->font.c_str());
|
||||||
if(e->h.isFromRequest()) {
|
if(e->h.isFromRequest()) {
|
||||||
Printf(false, " text = '%Fi%s%E' %Fl%Ll%f%D[change]%E",
|
Printf(true, " text = '%Fi%s%E' %Fl%Ll%f%D[change]%E",
|
||||||
e->str.c_str(), &ScreenEditTtfText, e->h.request().v);
|
e->str.c_str(), &ScreenEditTtfText, e->h.request().v);
|
||||||
|
Printf(true, " %Fd%f%D%Ll%s apply kerning",
|
||||||
|
&ScreenToggleTtfKerning, e->h.request().v,
|
||||||
|
e->extraPoints ? CHECK_TRUE : CHECK_FALSE);
|
||||||
Printf(true, " select new font");
|
Printf(true, " select new font");
|
||||||
SS.fonts.LoadAll();
|
SS.fonts.LoadAll();
|
||||||
// Not using range-for here because we use i inside the output.
|
// Not using range-for here because we use i inside the output.
|
||||||
|
|
|
@ -475,7 +475,8 @@ void Entity::GenerateBezierCurves(SBezierList *sbl) const {
|
||||||
Vector v = topLeft.Minus(botLeft);
|
Vector v = topLeft.Minus(botLeft);
|
||||||
Vector u = (v.Cross(n)).WithMagnitude(v.Magnitude());
|
Vector u = (v.Cross(n)).WithMagnitude(v.Magnitude());
|
||||||
|
|
||||||
SS.fonts.PlotString(font, str, sbl, botLeft, u, v);
|
// `extraPoints` is storing kerning boolean
|
||||||
|
SS.fonts.PlotString(font, str, sbl, extraPoints, botLeft, u, v);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,8 @@ void Request::Generate(IdList<Entity,hEntity> *entity,
|
||||||
// Request-specific generation.
|
// Request-specific generation.
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case Type::TTF_TEXT: {
|
case Type::TTF_TEXT: {
|
||||||
double actualAspectRatio = SS.fonts.AspectRatio(font, str);
|
// `extraPoints` is storing kerning boolean
|
||||||
|
double actualAspectRatio = SS.fonts.AspectRatio(font, str, extraPoints);
|
||||||
if(EXACT(actualAspectRatio != 0.0)) {
|
if(EXACT(actualAspectRatio != 0.0)) {
|
||||||
// We could load the font, so use the actual value.
|
// We could load the font, so use the actual value.
|
||||||
aspectRatio = actualAspectRatio;
|
aspectRatio = actualAspectRatio;
|
||||||
|
|
29
src/ttf.cpp
29
src/ttf.cpp
|
@ -108,11 +108,11 @@ TtfFont *TtfFontList::LoadFont(const std::string &font)
|
||||||
}
|
}
|
||||||
|
|
||||||
void TtfFontList::PlotString(const std::string &font, const std::string &str,
|
void TtfFontList::PlotString(const std::string &font, const std::string &str,
|
||||||
SBezierList *sbl, Vector origin, Vector u, Vector v)
|
SBezierList *sbl, bool kerning, Vector origin, Vector u, Vector v)
|
||||||
{
|
{
|
||||||
TtfFont *tf = LoadFont(font);
|
TtfFont *tf = LoadFont(font);
|
||||||
if(!str.empty() && tf != NULL) {
|
if(!str.empty() && tf != NULL) {
|
||||||
tf->PlotString(str, sbl, origin, u, v);
|
tf->PlotString(str, sbl, kerning, origin, u, v);
|
||||||
} else {
|
} else {
|
||||||
// No text or no font; so draw a big X for an error marker.
|
// No text or no font; so draw a big X for an error marker.
|
||||||
SBezier sb;
|
SBezier sb;
|
||||||
|
@ -123,11 +123,11 @@ void TtfFontList::PlotString(const std::string &font, const std::string &str,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double TtfFontList::AspectRatio(const std::string &font, const std::string &str)
|
double TtfFontList::AspectRatio(const std::string &font, const std::string &str, bool kerning)
|
||||||
{
|
{
|
||||||
TtfFont *tf = LoadFont(font);
|
TtfFont *tf = LoadFont(font);
|
||||||
if(tf != NULL) {
|
if(tf != NULL) {
|
||||||
return tf->AspectRatio(str);
|
return tf->AspectRatio(str, kerning);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0.0;
|
return 0.0;
|
||||||
|
@ -331,7 +331,7 @@ static int CubicTo(const FT_Vector *c1, const FT_Vector *c2, const FT_Vector *p,
|
||||||
}
|
}
|
||||||
|
|
||||||
void TtfFont::PlotString(const std::string &str,
|
void TtfFont::PlotString(const std::string &str,
|
||||||
SBezierList *sbl, Vector origin, Vector u, Vector v)
|
SBezierList *sbl, bool kerning, Vector origin, Vector u, Vector v)
|
||||||
{
|
{
|
||||||
ssassert(fontFace != NULL, "Expected font face to be loaded");
|
ssassert(fontFace != NULL, "Expected font face to be loaded");
|
||||||
|
|
||||||
|
@ -344,6 +344,7 @@ void TtfFont::PlotString(const std::string &str,
|
||||||
outlineFuncs.delta = 0;
|
outlineFuncs.delta = 0;
|
||||||
|
|
||||||
FT_Pos dx = 0;
|
FT_Pos dx = 0;
|
||||||
|
uint32_t prevGid = 0;
|
||||||
for(char32_t cid : ReadUTF8(str)) {
|
for(char32_t cid : ReadUTF8(str)) {
|
||||||
uint32_t gid = FT_Get_Char_Index(fontFace, cid);
|
uint32_t gid = FT_Get_Char_Index(fontFace, cid);
|
||||||
if (gid == 0) {
|
if (gid == 0) {
|
||||||
|
@ -382,6 +383,13 @@ void TtfFont::PlotString(const std::string &str,
|
||||||
*/
|
*/
|
||||||
FT_BBox cbox;
|
FT_BBox cbox;
|
||||||
FT_Outline_Get_CBox(&fontFace->glyph->outline, &cbox);
|
FT_Outline_Get_CBox(&fontFace->glyph->outline, &cbox);
|
||||||
|
|
||||||
|
// Apply Kerning, if any:
|
||||||
|
FT_Vector kernVector;
|
||||||
|
if(kerning && FT_Get_Kerning(fontFace, prevGid, gid, FT_KERNING_DEFAULT, &kernVector) == 0) {
|
||||||
|
dx += kernVector.x;
|
||||||
|
}
|
||||||
|
|
||||||
FT_Pos bx = dx - cbox.xMin;
|
FT_Pos bx = dx - cbox.xMin;
|
||||||
// Yes, this is what FreeType calls left-side bearing.
|
// Yes, this is what FreeType calls left-side bearing.
|
||||||
// Then interchangeably uses that with "left-side bearing". Sigh.
|
// Then interchangeably uses that with "left-side bearing". Sigh.
|
||||||
|
@ -402,14 +410,16 @@ void TtfFont::PlotString(const std::string &str,
|
||||||
// And we're done, so advance our position by the requested advance
|
// And we're done, so advance our position by the requested advance
|
||||||
// width, plus the user-requested extra advance.
|
// width, plus the user-requested extra advance.
|
||||||
dx += fontFace->glyph->advance.x;
|
dx += fontFace->glyph->advance.x;
|
||||||
|
prevGid = gid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double TtfFont::AspectRatio(const std::string &str) {
|
double TtfFont::AspectRatio(const std::string &str, bool kerning) {
|
||||||
ssassert(fontFace != NULL, "Expected font face to be loaded");
|
ssassert(fontFace != NULL, "Expected font face to be loaded");
|
||||||
|
|
||||||
// We always request a unit size character, so the aspect ratio is the same as advance length.
|
// We always request a unit size character, so the aspect ratio is the same as advance length.
|
||||||
double dx = 0;
|
double dx = 0;
|
||||||
|
uint32_t prevGid = 0;
|
||||||
for(char32_t chr : ReadUTF8(str)) {
|
for(char32_t chr : ReadUTF8(str)) {
|
||||||
uint32_t gid = FT_Get_Char_Index(fontFace, chr);
|
uint32_t gid = FT_Get_Char_Index(fontFace, chr);
|
||||||
if (gid == 0) {
|
if (gid == 0) {
|
||||||
|
@ -424,7 +434,14 @@ double TtfFont::AspectRatio(const std::string &str) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply Kerning, if any:
|
||||||
|
FT_Vector kernVector;
|
||||||
|
if(kerning && FT_Get_Kerning(fontFace, prevGid, gid, FT_KERNING_DEFAULT, &kernVector) == 0) {
|
||||||
|
dx += (double)kernVector.x / capHeight;
|
||||||
|
}
|
||||||
|
|
||||||
dx += (double)fontFace->glyph->advance.x / capHeight;
|
dx += (double)fontFace->glyph->advance.x / capHeight;
|
||||||
|
prevGid = gid;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dx;
|
return dx;
|
||||||
|
|
|
@ -24,8 +24,8 @@ public:
|
||||||
bool LoadFromResource(FT_LibraryRec_ *fontLibrary, bool keepOpen = false);
|
bool LoadFromResource(FT_LibraryRec_ *fontLibrary, bool keepOpen = false);
|
||||||
|
|
||||||
void PlotString(const std::string &str,
|
void PlotString(const std::string &str,
|
||||||
SBezierList *sbl, Vector origin, Vector u, Vector v);
|
SBezierList *sbl, bool kerning, Vector origin, Vector u, Vector v);
|
||||||
double AspectRatio(const std::string &str);
|
double AspectRatio(const std::string &str, bool kerning);
|
||||||
|
|
||||||
bool ExtractTTFData(bool keepOpen);
|
bool ExtractTTFData(bool keepOpen);
|
||||||
};
|
};
|
||||||
|
@ -43,8 +43,8 @@ public:
|
||||||
TtfFont *LoadFont(const std::string &font);
|
TtfFont *LoadFont(const std::string &font);
|
||||||
|
|
||||||
void PlotString(const std::string &font, const std::string &str,
|
void PlotString(const std::string &font, const std::string &str,
|
||||||
SBezierList *sbl, Vector origin, Vector u, Vector v);
|
SBezierList *sbl, bool kerning, Vector origin, Vector u, Vector v);
|
||||||
double AspectRatio(const std::string &font, const std::string &str);
|
double AspectRatio(const std::string &font, const std::string &str, bool kerning);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
1
src/ui.h
1
src/ui.h
|
@ -402,6 +402,7 @@ public:
|
||||||
// All of these are callbacks from the GUI code; first from when
|
// All of these are callbacks from the GUI code; first from when
|
||||||
// we're describing an entity
|
// we're describing an entity
|
||||||
static void ScreenEditTtfText(int link, uint32_t v);
|
static void ScreenEditTtfText(int link, uint32_t v);
|
||||||
|
static void ScreenToggleTtfKerning(int link, uint32_t v);
|
||||||
static void ScreenSetTtfFont(int link, uint32_t v);
|
static void ScreenSetTtfFont(int link, uint32_t v);
|
||||||
static void ScreenUnselectAll(int link, uint32_t v);
|
static void ScreenUnselectAll(int link, uint32_t v);
|
||||||
|
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 6.0 KiB |
|
@ -0,0 +1,331 @@
|
||||||
|
±²³SolveSpaceREVa
|
||||||
|
|
||||||
|
|
||||||
|
Group.h.v=00000001
|
||||||
|
Group.type=5000
|
||||||
|
Group.name=#references
|
||||||
|
Group.color=ff000000
|
||||||
|
Group.skipFirst=0
|
||||||
|
Group.predef.swapUV=0
|
||||||
|
Group.predef.negateU=0
|
||||||
|
Group.predef.negateV=0
|
||||||
|
Group.visible=1
|
||||||
|
Group.suppress=0
|
||||||
|
Group.relaxConstraints=0
|
||||||
|
Group.allowRedundant=0
|
||||||
|
Group.allDimsReference=0
|
||||||
|
Group.scale=1.00000000000000000000
|
||||||
|
Group.remap={
|
||||||
|
}
|
||||||
|
AddGroup
|
||||||
|
|
||||||
|
Group.h.v=00000002
|
||||||
|
Group.type=5001
|
||||||
|
Group.order=1
|
||||||
|
Group.name=sketch-in-plane
|
||||||
|
Group.activeWorkplane.v=80020000
|
||||||
|
Group.color=ff000000
|
||||||
|
Group.subtype=6000
|
||||||
|
Group.skipFirst=0
|
||||||
|
Group.predef.q.w=1.00000000000000000000
|
||||||
|
Group.predef.origin.v=00010001
|
||||||
|
Group.predef.swapUV=0
|
||||||
|
Group.predef.negateU=0
|
||||||
|
Group.predef.negateV=0
|
||||||
|
Group.visible=1
|
||||||
|
Group.suppress=0
|
||||||
|
Group.relaxConstraints=0
|
||||||
|
Group.allowRedundant=0
|
||||||
|
Group.allDimsReference=0
|
||||||
|
Group.scale=1.00000000000000000000
|
||||||
|
Group.remap={
|
||||||
|
}
|
||||||
|
AddGroup
|
||||||
|
|
||||||
|
Param.h.v.=00010010
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00010011
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00010012
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00010020
|
||||||
|
Param.val=1.00000000000000000000
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00010021
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00010022
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00010023
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00020010
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00020011
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00020012
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00020020
|
||||||
|
Param.val=0.50000000000000000000
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00020021
|
||||||
|
Param.val=0.50000000000000000000
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00020022
|
||||||
|
Param.val=0.50000000000000000000
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00020023
|
||||||
|
Param.val=0.50000000000000000000
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00030010
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00030011
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00030012
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00030020
|
||||||
|
Param.val=0.50000000000000000000
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00030021
|
||||||
|
Param.val=-0.50000000000000000000
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00030022
|
||||||
|
Param.val=-0.50000000000000000000
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00030023
|
||||||
|
Param.val=-0.50000000000000000000
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00040010
|
||||||
|
Param.val=-5.00000000000000000000
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00040011
|
||||||
|
Param.val=5.00000000000000000000
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00040013
|
||||||
|
Param.val=-5.00000000000000000000
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00040014
|
||||||
|
Param.val=-5.00000000000000000000
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00040016
|
||||||
|
Param.val=23.08769405528209262002
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00040017
|
||||||
|
Param.val=-5.00000000000000000000
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=00040019
|
||||||
|
Param.val=23.08769405528209262002
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Param.h.v.=0004001a
|
||||||
|
Param.val=5.00000000000000000000
|
||||||
|
AddParam
|
||||||
|
|
||||||
|
Request.h.v=00000001
|
||||||
|
Request.type=100
|
||||||
|
Request.group.v=00000001
|
||||||
|
Request.construction=0
|
||||||
|
AddRequest
|
||||||
|
|
||||||
|
Request.h.v=00000002
|
||||||
|
Request.type=100
|
||||||
|
Request.group.v=00000001
|
||||||
|
Request.construction=0
|
||||||
|
AddRequest
|
||||||
|
|
||||||
|
Request.h.v=00000003
|
||||||
|
Request.type=100
|
||||||
|
Request.group.v=00000001
|
||||||
|
Request.construction=0
|
||||||
|
AddRequest
|
||||||
|
|
||||||
|
Request.h.v=00000004
|
||||||
|
Request.type=600
|
||||||
|
Request.extraPoints=1
|
||||||
|
Request.workplane.v=80020000
|
||||||
|
Request.group.v=00000002
|
||||||
|
Request.construction=0
|
||||||
|
Request.str=Text
|
||||||
|
Request.font=Gentium-R.ttf
|
||||||
|
Request.aspectRatio=2.80876940552820908437
|
||||||
|
AddRequest
|
||||||
|
|
||||||
|
Entity.h.v=00010000
|
||||||
|
Entity.type=10000
|
||||||
|
Entity.construction=0
|
||||||
|
Entity.point[0].v=00010001
|
||||||
|
Entity.normal.v=00010020
|
||||||
|
Entity.actVisible=1
|
||||||
|
AddEntity
|
||||||
|
|
||||||
|
Entity.h.v=00010001
|
||||||
|
Entity.type=2000
|
||||||
|
Entity.construction=1
|
||||||
|
Entity.actVisible=1
|
||||||
|
AddEntity
|
||||||
|
|
||||||
|
Entity.h.v=00010020
|
||||||
|
Entity.type=3000
|
||||||
|
Entity.construction=0
|
||||||
|
Entity.point[0].v=00010001
|
||||||
|
Entity.actNormal.w=1.00000000000000000000
|
||||||
|
Entity.actVisible=1
|
||||||
|
AddEntity
|
||||||
|
|
||||||
|
Entity.h.v=00020000
|
||||||
|
Entity.type=10000
|
||||||
|
Entity.construction=0
|
||||||
|
Entity.point[0].v=00020001
|
||||||
|
Entity.normal.v=00020020
|
||||||
|
Entity.actVisible=1
|
||||||
|
AddEntity
|
||||||
|
|
||||||
|
Entity.h.v=00020001
|
||||||
|
Entity.type=2000
|
||||||
|
Entity.construction=1
|
||||||
|
Entity.actVisible=1
|
||||||
|
AddEntity
|
||||||
|
|
||||||
|
Entity.h.v=00020020
|
||||||
|
Entity.type=3000
|
||||||
|
Entity.construction=0
|
||||||
|
Entity.point[0].v=00020001
|
||||||
|
Entity.actNormal.w=0.50000000000000000000
|
||||||
|
Entity.actNormal.vx=0.50000000000000000000
|
||||||
|
Entity.actNormal.vy=0.50000000000000000000
|
||||||
|
Entity.actNormal.vz=0.50000000000000000000
|
||||||
|
Entity.actVisible=1
|
||||||
|
AddEntity
|
||||||
|
|
||||||
|
Entity.h.v=00030000
|
||||||
|
Entity.type=10000
|
||||||
|
Entity.construction=0
|
||||||
|
Entity.point[0].v=00030001
|
||||||
|
Entity.normal.v=00030020
|
||||||
|
Entity.actVisible=1
|
||||||
|
AddEntity
|
||||||
|
|
||||||
|
Entity.h.v=00030001
|
||||||
|
Entity.type=2000
|
||||||
|
Entity.construction=1
|
||||||
|
Entity.actVisible=1
|
||||||
|
AddEntity
|
||||||
|
|
||||||
|
Entity.h.v=00030020
|
||||||
|
Entity.type=3000
|
||||||
|
Entity.construction=0
|
||||||
|
Entity.point[0].v=00030001
|
||||||
|
Entity.actNormal.w=0.50000000000000000000
|
||||||
|
Entity.actNormal.vx=-0.50000000000000000000
|
||||||
|
Entity.actNormal.vy=-0.50000000000000000000
|
||||||
|
Entity.actNormal.vz=-0.50000000000000000000
|
||||||
|
Entity.actVisible=1
|
||||||
|
AddEntity
|
||||||
|
|
||||||
|
Entity.h.v=00040000
|
||||||
|
Entity.type=15000
|
||||||
|
Entity.construction=0
|
||||||
|
Entity.str=Text
|
||||||
|
Entity.font=Gentium-R.ttf
|
||||||
|
Entity.point[0].v=00040001
|
||||||
|
Entity.point[1].v=00040002
|
||||||
|
Entity.point[2].v=00040003
|
||||||
|
Entity.point[3].v=00040004
|
||||||
|
Entity.extraPoints=1
|
||||||
|
Entity.normal.v=00040020
|
||||||
|
Entity.workplane.v=80020000
|
||||||
|
Entity.actVisible=1
|
||||||
|
AddEntity
|
||||||
|
|
||||||
|
Entity.h.v=00040001
|
||||||
|
Entity.type=2001
|
||||||
|
Entity.construction=0
|
||||||
|
Entity.workplane.v=80020000
|
||||||
|
Entity.actPoint.x=-5.00000000000000000000
|
||||||
|
Entity.actPoint.y=5.00000000000000000000
|
||||||
|
Entity.actVisible=1
|
||||||
|
AddEntity
|
||||||
|
|
||||||
|
Entity.h.v=00040002
|
||||||
|
Entity.type=2001
|
||||||
|
Entity.construction=0
|
||||||
|
Entity.workplane.v=80020000
|
||||||
|
Entity.actPoint.x=-5.00000000000000000000
|
||||||
|
Entity.actPoint.y=-5.00000000000000000000
|
||||||
|
Entity.actVisible=1
|
||||||
|
AddEntity
|
||||||
|
|
||||||
|
Entity.h.v=00040003
|
||||||
|
Entity.type=2001
|
||||||
|
Entity.construction=0
|
||||||
|
Entity.workplane.v=80020000
|
||||||
|
Entity.actPoint.x=23.08769405528209262002
|
||||||
|
Entity.actPoint.y=-5.00000000000000000000
|
||||||
|
Entity.actVisible=1
|
||||||
|
AddEntity
|
||||||
|
|
||||||
|
Entity.h.v=00040004
|
||||||
|
Entity.type=2001
|
||||||
|
Entity.construction=0
|
||||||
|
Entity.workplane.v=80020000
|
||||||
|
Entity.actPoint.x=23.08769405528209262002
|
||||||
|
Entity.actPoint.y=5.00000000000000000000
|
||||||
|
Entity.actVisible=1
|
||||||
|
AddEntity
|
||||||
|
|
||||||
|
Entity.h.v=00040020
|
||||||
|
Entity.type=3001
|
||||||
|
Entity.construction=0
|
||||||
|
Entity.point[0].v=00040001
|
||||||
|
Entity.workplane.v=80020000
|
||||||
|
Entity.actNormal.w=1.00000000000000000000
|
||||||
|
Entity.actVisible=1
|
||||||
|
AddEntity
|
||||||
|
|
||||||
|
Entity.h.v=80020000
|
||||||
|
Entity.type=10000
|
||||||
|
Entity.construction=0
|
||||||
|
Entity.point[0].v=80020002
|
||||||
|
Entity.normal.v=80020001
|
||||||
|
Entity.actVisible=1
|
||||||
|
AddEntity
|
||||||
|
|
||||||
|
Entity.h.v=80020001
|
||||||
|
Entity.type=3010
|
||||||
|
Entity.construction=0
|
||||||
|
Entity.point[0].v=80020002
|
||||||
|
Entity.actNormal.w=1.00000000000000000000
|
||||||
|
Entity.actVisible=1
|
||||||
|
AddEntity
|
||||||
|
|
||||||
|
Entity.h.v=80020002
|
||||||
|
Entity.type=2012
|
||||||
|
Entity.construction=1
|
||||||
|
Entity.actVisible=1
|
||||||
|
AddEntity
|
||||||
|
|
|
@ -6,6 +6,12 @@ TEST_CASE(normal_roundtrip) {
|
||||||
CHECK_SAVE("normal.slvs");
|
CHECK_SAVE("normal.slvs");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE(kerning_roundtrip) {
|
||||||
|
CHECK_LOAD("kerning.slvs");
|
||||||
|
CHECK_RENDER("kerning.png");
|
||||||
|
CHECK_SAVE("kerning.slvs");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE(normal_migrate_from_v20) {
|
TEST_CASE(normal_migrate_from_v20) {
|
||||||
CHECK_LOAD("normal_v20.slvs");
|
CHECK_LOAD("normal_v20.slvs");
|
||||||
CHECK_SAVE("normal.slvs");
|
CHECK_SAVE("normal.slvs");
|
||||||
|
|
Loading…
Reference in New Issue