Skip to content

Commit 8a4c89c

Browse files
committed
Fix some bugs on unix font
1 parent 70515a9 commit 8a4c89c

File tree

3 files changed

+85
-86
lines changed

3 files changed

+85
-86
lines changed

modules/ILL/ILL.moon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module_version = "1.4.7"
1+
module_version = "1.4.8"
22

33
haveDepCtrl, DependencyControl = pcall require, "l0.DependencyControl"
44

modules/ILL/ILL/Ass/Line.moon

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
-- https://github.com/Aegisub/Aegisub/blob/master/automation/include/karaskel-auto4.lua
22

3+
-- Uses WinGDI and FreeType to capture metrics
34
-- This is a copy of "karaskel-auto4.lua" in order to further explore the metrics
4-
-- provided by the Aegisub API
55

66
import Aegi from require "ILL.ILL.Aegi"
77
import Math from require "ILL.ILL.Math"
@@ -76,10 +76,6 @@ class Line
7676
if value = .reset.data[name]
7777
.data[name] = value
7878

79-
-- resizes the font size value according to the set ratio
80-
if .ratio
81-
.data.fontsize *= .ratio
82-
8379
-- if it's a shape, this information are irrelevant
8480
unless .isShape
8581
-- gets the value of the width of a space

modules/ILL/ILL/Font/Unx.moon

Lines changed: 83 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -357,22 +357,21 @@ cdef [[
357357
int nobject;
358358
int sobject;
359359
const char** objects;
360-
}FcObjectSet;
360+
} FcObjectSet;
361361
typedef struct{
362362
int nfont;
363363
int sfont;
364364
FcPattern** fonts;
365-
}FcFontSet;
365+
} FcFontSet;
366366
typedef enum{
367-
FcResultMatch,
368-
FcResultNoMatch,
369-
FcResultTypeMismatch,
370-
FcResultNoId,
371-
FcResultOutOfMemory
372-
}FcResult;
367+
FcResultMatchILL,
368+
FcResultNoMatchILL,
369+
FcResultTypeMismatchILL,
370+
FcResultNoIdILL,
371+
FcResultOutOfMemoryILL
372+
} FcResult;
373373
typedef unsigned char FcChar8;
374374
typedef int FcBool;
375-
376375
FcConfig* FcInitLoadConfigAndFonts(void);
377376
FcPattern* FcPatternCreate(void);
378377
void FcPatternDestroy(FcPattern*);
@@ -388,84 +387,83 @@ import Math from require "ILL.ILL.Math"
388387
import UTF8 from require "ILL.ILL.UTF8"
389388
import Init from require "ILL.ILL.Font.Init"
390389

391-
-- https://github.com/libass/libass/blob/17cb8da964c852835881658d0d7af35ef2d92f9e/libass/ass_font.c#L502
390+
-- https://github.com/libass/libass/blob/db83d6770ba11cb9ef72f4a9de7a0e2b1dd7baa3/libass/ass_font.c#L277
392391
set_font_metrics = (face) ->
393-
-- Mimicking GDI's behavior for asc/desc/height.
394-
-- These fields are (apparently) sometimes used for signed values,
395-
-- despite being unsigned in the spec.
396-
os2 = ffi.cast "TT_OS2*", C.FT_Get_Sfnt_Table face, C.FT_SFNT_OS2
397-
if os2 and (tonumber(os2.usWinAscent) + tonumber(os2.usWinDescent) != 0)
398-
face.ascender = tonumber os2.usWinAscent
399-
face.descender = -tonumber os2.usWinDescent
400-
face.height = face.ascender - face.descender
401-
402-
-- If we didn't have usable Win values in the OS/2 table,
403-
-- then the values from FreeType will still be in these fields.
404-
-- It'll use either the OS/2 typo metrics or the hhea ones.
405-
-- If the font has typo metrics but FreeType didn't use them
406-
-- (either old FT or USE_TYPO_METRICS not set), we'll try those.
407-
-- In the case of a very broken font that has none of those options,
408-
-- we fall back on using face.bbox.
409-
-- Anything without valid OS/2 Win values isn't supported by VSFilter,
410-
-- so at this point compatibility's out the window and we're just
411-
-- trying to render _something_ readable.
412-
if face.ascender - face.descender == 0 or face.height == 0
413-
if os2 and (tonumber(os2.sTypoAscender) - tonumber(os2.sTypoDescender) != 0)
414-
face.ascender = tonumber os2.sTypoAscender
415-
face.descender = tonumber os2.sTypoDescender
416-
face.height = face.ascender - face.descender
417-
else
418-
face.ascender = tonumber face.bbox.yMax
419-
face.descender = tonumber face.bbox.yMin
420-
face.height = face.ascender - face.descender
392+
-- Mimicking GDI's behavior for asc/desc/height.
393+
-- These fields are (apparently) sometimes used for signed values,
394+
-- despite being unsigned in the spec.
395+
os2 = ffi.cast "TT_OS2*", C.FT_Get_Sfnt_Table face, C.FT_SFNT_OS2
396+
if os2 and (tonumber(os2.usWinAscent) + tonumber(os2.usWinDescent) != 0)
397+
face.ascender = tonumber os2.usWinAscent
398+
face.descender = -tonumber os2.usWinDescent
399+
face.height = face.ascender - face.descender
400+
401+
-- If we didn't have usable Win values in the OS/2 table,
402+
-- then the values from FreeType will still be in these fields.
403+
-- It'll use either the OS/2 typo metrics or the hhea ones.
404+
-- If the font has typo metrics but FreeType didn't use them
405+
-- (either old FT or USE_TYPO_METRICS not set), we'll try those.
406+
-- In the case of a very broken font that has none of those options,
407+
-- we fall back on using face.bbox.
408+
-- Anything without valid OS/2 Win values isn't supported by VSFilter,
409+
-- so at this point compatibility's out the window and we're just
410+
-- trying to render _something_ readable.
411+
if face.ascender - face.descender == 0 or face.height == 0
412+
if os2 and (tonumber(os2.sTypoAscender) - tonumber(os2.sTypoDescender) != 0)
413+
face.ascender = tonumber os2.sTypoAscender
414+
face.descender = tonumber os2.sTypoDescender
415+
face.height = face.ascender - face.descender
416+
else
417+
face.ascender = tonumber face.bbox.yMax
418+
face.descender = tonumber face.bbox.yMin
419+
face.height = face.ascender - face.descender
421420

422421
-- https://github.com/libass/libass/blob/17cb8da964c852835881658d0d7af35ef2d92f9e/libass/ass_font.c#L502
423422
ass_face_set_size = (face, size) ->
424-
rq = ffi.new "FT_Size_RequestRec"
425-
ffi.C.memset rq, 0, ffi.sizeof rq
426-
rq.type = ffi.C.FT_SIZE_REQUEST_TYPE_REAL_DIM
427-
rq.width = 0
428-
rq.height = size * FONT_UPSCALE
429-
rq.horiResolution = 0
430-
rq.vertResolution = 0
431-
freetype.FT_Request_Size face, rq
432-
433-
-- https://github.com/libass/libass/blob/17cb8da964c852835881658d0d7af35ef2d92f9e/libass/ass_font.c#L502
423+
rq = ffi.new "FT_Size_RequestRec"
424+
ffi.C.memset rq, 0, ffi.sizeof rq
425+
rq.type = ffi.C.FT_SIZE_REQUEST_TYPE_REAL_DIM
426+
rq.width = 0
427+
rq.height = size * FONT_UPSCALE
428+
rq.horiResolution = 0
429+
rq.vertResolution = 0
430+
freetype.FT_Request_Size face, rq
431+
432+
-- https://github.com/libass/libass/blob/db83d6770ba11cb9ef72f4a9de7a0e2b1dd7baa3/libass/ass_font.c#L502
434433
ass_font_get_asc_desc = (face) ->
435434
y_scale = face.size.metrics.y_scale
436435
ascender = freetype.FT_MulFix face.ascender, y_scale
437436
descender = freetype.FT_MulFix -face.descender, y_scale
438437
return tonumber(ascender) / FONT_UPSCALE, tonumber(descender) / FONT_UPSCALE
439438

439+
-- https://github.com/libass/libass/blob/db83d6770ba11cb9ef72f4a9de7a0e2b1dd7baa3/libass/ass_font.c#L516
440440
ass_face_get_weight = (face) ->
441-
os2 = ffi.cast "TT_OS2*", freetype.FT_Get_Sfnt_Table face, C.FT_SFNT_OS2
442-
os2Weight = os2 and tonumber(os2.usWeightClass) or 0
443-
styleFlags = tonumber face.style_flags
444-
if os2Weight == 0
445-
return 300 * (styleFlags != 0x1) + 400
446-
elseif os2Weight >= 1 and os2Weight <= 9
447-
return os2Weight * 100
448-
else
449-
return os2Weight
450-
451-
-- https://github.com/libass/libass/blob/ffe070bbfbc77e3ab731aac5ec24fa63aeb461af/libass/ass_font.c#L561C1-L572C2
441+
os2 = ffi.cast "TT_OS2*", freetype.FT_Get_Sfnt_Table face, C.FT_SFNT_OS2
442+
os2Weight = os2 and tonumber(os2.usWeightClass) or 0
443+
styleFlags = tonumber face.style_flags
444+
if os2Weight == 0
445+
return 300 * (styleFlags != 0x1) + 400
446+
elseif os2Weight >= 1 and os2Weight <= 9
447+
return os2Weight * 100
448+
else
449+
return os2Weight
450+
451+
-- https://github.com/libass/libass/blob/db83d6770ba11cb9ef72f4a9de7a0e2b1dd7baa3/libass/ass_font.c#L561
452452
ass_glyph_embolden = (slot) ->
453-
if slot.format != ffi.C.FT_GLYPH_FORMAT_OUTLINE
454-
return
455-
str = freetype.FT_MulFix(slot.face.units_per_EM, slot.face.size.metrics.y_scale) / FONT_UPSCALE
456-
freetype.FT_Outline_Embolden slot.outline, str
457-
return
453+
if slot.format != ffi.C.FT_GLYPH_FORMAT_OUTLINE
454+
return
455+
str = freetype.FT_MulFix(slot.face.units_per_EM, slot.face.size.metrics.y_scale) / FONT_UPSCALE
456+
freetype.FT_Outline_Embolden slot.outline, str
458457

459-
-- https://github.com/libass/libass/blob/ffe070bbfbc77e3ab731aac5ec24fa63aeb461af/libass/ass_font.c#L577
458+
-- https://github.com/libass/libass/blob/db83d6770ba11cb9ef72f4a9de7a0e2b1dd7baa3/libass/ass_font.c#L577
460459
ass_glyph_italicize = (slot) ->
461-
xfrm = ffi.new "FT_Matrix", {
462-
xx: 0x10000
463-
xy: 0x05700
464-
yx: 0x00000
465-
yy: 0x10000
466-
}
467-
freetype.FT_Outline_Transform slot.outline, xfrm
468-
return
460+
xfrm = ffi.new "FT_Matrix", {
461+
xx: 0x10000
462+
xy: 0x05700
463+
yx: 0x00000
464+
yy: 0x10000
465+
}
466+
freetype.FT_Outline_Transform slot.outline, xfrm
469467

470468
class FreeType extends Init
471469

@@ -519,7 +517,7 @@ class FreeType extends Init
519517
ascent: @ascender * @yscale
520518
descent: @descender * @yscale
521519
height: @height * @yscale
522-
internal_leading: @ascender - @descender - (@face[0].units_per_EM / FONT_UPSCALE)
520+
internal_leading: (@ascender - @descender - (@face[0].units_per_EM / FONT_UPSCALE)) * @yscale
523521
external_leading: 0
524522
}
525523

@@ -529,7 +527,7 @@ class FreeType extends Init
529527
@callBackChars text, (ci, char, glyph) ->
530528
width += tonumber(glyph.metrics.horiAdvance) + (ci > 1 and @hspace * FONT_UPSCALE or 0)
531529
{
532-
width: width / FONT_UPSCALE
530+
width: (width / FONT_UPSCALE) * @xscale
533531
height: @height * @yscale
534532
}
535533

@@ -570,6 +568,11 @@ class FreeType extends Init
570568
err = freetype.FT_Outline_Decompose glyph.outline, outline_funcs, nil
571569
if err != 0
572570
error "Failed to load the freetype outline decompose", 2
571+
-- Frees up memory stored for callbacks
572+
outline_funcs[0].move_to\free!
573+
outline_funcs[0].line_to\free!
574+
outline_funcs[0].conic_to\free!
575+
outline_funcs[0].cubic_to\free!
573576
-- Converts quadratic curves to bezier
574577
for i = 1, #build
575578
val = build[i]
@@ -602,15 +605,15 @@ class FreeType extends Init
602605
for i = 0, fontset[0].nfont - 1
603606
font = fontset[0].fonts[i]
604607
family, fullname, style, outline, file = nil, nil, nil, nil, nil
605-
if fontconfig.FcPatternGetString(font, "family", 0, cstr) == ffi.C.FcResultMatch
608+
if fontconfig.FcPatternGetString(font, "family", 0, cstr) == ffi.C.FcResultMatchILL
606609
family = ffi.string cstr[0]
607-
if fontconfig.FcPatternGetString(font, "fullname", 0, cstr) == ffi.C.FcResultMatch
610+
if fontconfig.FcPatternGetString(font, "fullname", 0, cstr) == ffi.C.FcResultMatchILL
608611
fullname = ffi.string cstr[0]
609-
if fontconfig.FcPatternGetString(font, "style", 0, cstr) == ffi.C.FcResultMatch
612+
if fontconfig.FcPatternGetString(font, "style", 0, cstr) == ffi.C.FcResultMatchILL
610613
style = ffi.string cstr[0]
611-
if fontconfig.FcPatternGetBool(font, "outline", 0, cbool) == ffi.C.FcResultMatch
614+
if fontconfig.FcPatternGetBool(font, "outline", 0, cbool) == ffi.C.FcResultMatchILL
612615
outline = cbool[0]
613-
if fontconfig.FcPatternGetString(font, "file", 0, cstr) == ffi.C.FcResultMatch
616+
if fontconfig.FcPatternGetString(font, "file", 0, cstr) == ffi.C.FcResultMatchILL
614617
file = ffi.string cstr[0]
615618
if family and fullname and style and outline
616619
fonts.n += 1

0 commit comments

Comments
 (0)