Werner Lemberg pushed to branch wl/sbix at FreeType / FreeType
Commits:
-
7c6b2f20
by Alexei Podtelezhnikov at 2022-02-08T14:37:34+00:00
-
ed0e2e76
by Alexei Podtelezhnikov at 2022-02-08T16:35:14-05:00
-
0447df71
by Alexei Podtelezhnikov at 2022-02-09T15:04:58+00:00
-
1680885a
by Alexei Podtelezhnikov at 2022-02-09T16:41:07+00:00
-
338b4e88
by Werner Lemberg at 2022-02-11T19:32:49+01:00
-
c67ecb8c
by Werner Lemberg at 2022-02-12T07:52:57+01:00
-
5a53e51b
by Werner Lemberg at 2022-02-12T07:58:43+01:00
-
00ae29fc
by Alexei Podtelezhnikov at 2022-02-12T23:42:08-05:00
-
01d4deb0
by Werner Lemberg at 2022-02-16T14:51:44+01:00
-
20ec99be
by Steve Lhomme at 2022-02-17T13:35:52-05:00
-
5b26e92a
by Werner Lemberg at 2022-02-19T07:20:24+01:00
-
ca46bc0c
by Werner Lemberg at 2022-02-19T13:36:25+01:00
-
6c5522c6
by Werner Lemberg at 2022-02-19T13:37:07+01:00
-
bcdfa386
by suzuki toshiya at 2022-02-21T10:44:42+09:00
-
034e5dbf
by Ben Wagner at 2022-02-23T17:42:55+01:00
-
335224be
by Ben Wagner at 2022-03-03T16:42:54-05:00
-
5499d7bf
by Anuj Verma at 2022-03-05T16:44:23+01:00
-
2600ef63
by Anuj Verma at 2022-03-05T16:53:45+01:00
-
360e2507
by Anuj Verma at 2022-03-05T17:00:10+01:00
-
1e2eb650
by Werner Lemberg at 2022-03-07T10:13:44+01:00
-
2030208e
by Werner Lemberg at 2022-03-13T16:58:58+01:00
-
e853eb62
by Werner Lemberg at 2022-03-13T16:58:58+01:00
-
d4aeeeeb
by Werner Lemberg at 2022-03-13T16:58:58+01:00
21 changed files:
- CMakeLists.txt
- builds/mac/ftmac.c
- builds/windows/ftsystem.c
- docs/CHANGES
- include/freetype/freetype.h
- include/freetype/ftmm.h
- include/freetype/t1tables.h
- src/base/ftmac.c
- src/bdf/README
- src/psaux/psintrp.c
- src/pshinter/pshalgo.c
- src/pshinter/pshrec.c
- src/sdf/ftsdf.c
- src/sdf/ftsdfcommon.h
- src/sfnt/sfobjs.c
- src/sfnt/ttcolr.c
- src/sfnt/ttkern.c
- src/sfnt/ttsbit.c
- src/sfnt/ttsvg.c
- src/truetype/ttgload.c
- src/type42/t42drivr.c
Changes:
... | ... | @@ -106,10 +106,9 @@ |
106 | 106 | # (this is compatible with the same CMake variables in zlib's CMake
|
107 | 107 | # support).
|
108 | 108 | |
109 | -# FreeType explicitly marks the API to be exported and relies on the compiler
|
|
110 | -# to hide all other symbols. CMake supports a C_VISBILITY_PRESET property
|
|
111 | -# starting with 2.8.12.
|
|
112 | -cmake_minimum_required(VERSION 2.8.12)
|
|
109 | +# To minimize the number of cmake_policy() workarounds,
|
|
110 | +# CMake >= 3 is requested.
|
|
111 | +cmake_minimum_required(VERSION 3.0)
|
|
113 | 112 | |
114 | 113 | if (NOT CMAKE_VERSION VERSION_LESS 3.3)
|
115 | 114 | # Allow symbol visibility settings also on static libraries. CMake < 3.3
|
... | ... | @@ -97,7 +97,7 @@ |
97 | 97 | |
98 | 98 | #define FT_DEPRECATED_ATTRIBUTE
|
99 | 99 | |
100 | -#include FT_MAC_H
|
|
100 | +#include <freetype/ftmac.h>
|
|
101 | 101 | |
102 | 102 | /* undefine blocking-macros in ftmac.h */
|
103 | 103 | #undef FT_GetFile_From_Mac_Name
|
... | ... | @@ -196,7 +196,25 @@ |
196 | 196 | }
|
197 | 197 | |
198 | 198 | |
199 | -#ifdef _WIN32_WCE
|
|
199 | +#if defined( NTDDI_VERSION ) && NTDDI_VERSION < 0x0A000007 && \
|
|
200 | + defined( WINAPI_FAMILY_PARTITION ) && \
|
|
201 | + !WINAPI_FAMILY_PARTITION( WINAPI_PARTITION_DESKTOP )
|
|
202 | + |
|
203 | +#define PACK_DWORD64( hi, lo ) ( ( (DWORD64)(hi) << 32 ) | (DWORD)(lo) )
|
|
204 | + |
|
205 | +#define CreateFileW( a, b, c, d, e, f, g ) \
|
|
206 | + CreateFileFromAppW( a, b, c, d, e, f, g )
|
|
207 | +#define CreateFileMapping( a, b, c, d, e, f ) \
|
|
208 | + CreateFileMappingFromApp( a, b, c, PACK_DWORD64( d, e ), f )
|
|
209 | +#define MapViewOfFile( a, b, c, d, e ) \
|
|
210 | + MapViewOfFileFromApp( a, b, PACK_DWORD64( c, d ), e )
|
|
211 | + |
|
212 | +#define UWP_LEGACY
|
|
213 | + |
|
214 | +#endif
|
|
215 | + |
|
216 | + |
|
217 | +#if defined( _WIN32_WCE ) || defined( UWP_LEGACY )
|
|
200 | 218 | |
201 | 219 | FT_LOCAL_DEF( HANDLE )
|
202 | 220 | CreateFileA( LPCSTR lpFileName,
|
... | ... | @@ -12,6 +12,16 @@ CHANGES BETWEEN 2.11.1 and 2.12.0 |
12 | 12 | |
13 | 13 | This work was Moazin Kathri's GSoC 2019 project.
|
14 | 14 | |
15 | + II. MISCELLANEOUS
|
|
16 | + |
|
17 | + - The internal 'zlib' code has been updated to be in sync with the
|
|
18 | + current 'zlib' version (1.2.11).
|
|
19 | + |
|
20 | + - Some minor improvements of the building systems, in particular
|
|
21 | + handling of the 'zlib' library (internal vs. external).
|
|
22 | + |
|
23 | + - Various other minor bug and documentation fixes.
|
|
24 | + |
|
15 | 25 | |
16 | 26 | ======================================================================
|
17 | 27 |
... | ... | @@ -154,6 +154,7 @@ FT_BEGIN_HEADER |
154 | 154 | * FT_FACE_FLAG_EXTERNAL_STREAM
|
155 | 155 | * FT_FACE_FLAG_HINTER
|
156 | 156 | * FT_FACE_FLAG_SVG
|
157 | + * FT_FACE_FLAG_SBIX
|
|
157 | 158 | *
|
158 | 159 | * FT_HAS_HORIZONTAL
|
159 | 160 | * FT_HAS_VERTICAL
|
... | ... | @@ -163,6 +164,7 @@ FT_BEGIN_HEADER |
163 | 164 | * FT_HAS_COLOR
|
164 | 165 | * FT_HAS_MULTIPLE_MASTERS
|
165 | 166 | * FT_HAS_SVG
|
167 | + * FT_HAS_SBIX
|
|
166 | 168 | *
|
167 | 169 | * FT_IS_SFNT
|
168 | 170 | * FT_IS_SCALABLE
|
... | ... | @@ -227,6 +229,7 @@ FT_BEGIN_HEADER |
227 | 229 | * FT_LOAD_NO_SCALE
|
228 | 230 | * FT_LOAD_NO_HINTING
|
229 | 231 | * FT_LOAD_NO_BITMAP
|
232 | + * FT_LOAD_SBITS_ONLY
|
|
230 | 233 | * FT_LOAD_NO_AUTOHINT
|
231 | 234 | * FT_LOAD_COLOR
|
232 | 235 | *
|
... | ... | @@ -1235,6 +1238,9 @@ FT_BEGIN_HEADER |
1235 | 1238 | *
|
1236 | 1239 | * FT_FACE_FLAG_SVG ::
|
1237 | 1240 | * [Since 2.12] The face has an 'SVG~' OpenType table.
|
1241 | + *
|
|
1242 | + * FT_FACE_FLAG_SBIX ::
|
|
1243 | + * [Since 2.12] The face has an 'sbix' OpenType table.
|
|
1238 | 1244 | */
|
1239 | 1245 | #define FT_FACE_FLAG_SCALABLE ( 1L << 0 )
|
1240 | 1246 | #define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 )
|
... | ... | @@ -1253,6 +1259,7 @@ FT_BEGIN_HEADER |
1253 | 1259 | #define FT_FACE_FLAG_COLOR ( 1L << 14 )
|
1254 | 1260 | #define FT_FACE_FLAG_VARIATION ( 1L << 15 )
|
1255 | 1261 | #define FT_FACE_FLAG_SVG ( 1L << 16 )
|
1262 | +#define FT_FACE_FLAG_SBIX ( 1L << 17 )
|
|
1256 | 1263 | |
1257 | 1264 | |
1258 | 1265 | /**************************************************************************
|
... | ... | @@ -1509,6 +1516,68 @@ FT_BEGIN_HEADER |
1509 | 1516 | ( !!( (face)->face_flags & FT_FACE_FLAG_SVG ) )
|
1510 | 1517 | |
1511 | 1518 | |
1519 | + /**************************************************************************
|
|
1520 | + *
|
|
1521 | + * @macro:
|
|
1522 | + * FT_HAS_SBIX
|
|
1523 | + *
|
|
1524 | + * @description:
|
|
1525 | + * A macro that returns true whenever a face object contains an 'sbix'
|
|
1526 | + * OpenType table.
|
|
1527 | + *
|
|
1528 | + * @note:
|
|
1529 | + * Here is some pseudo code that roughly illustrates how to implement
|
|
1530 | + * 'sbix' handling according to the OpenType specification.
|
|
1531 | + *
|
|
1532 | + * ```
|
|
1533 | + * if ( FT_HAS_SBIX( face ) )
|
|
1534 | + * {
|
|
1535 | + * <sort `face->available_size` as necessary into
|
|
1536 | + * `preferred_sizes`[*]>
|
|
1537 | + *
|
|
1538 | + * for ( i = 0; i < face->num_fixed_sizes; i++ )
|
|
1539 | + * {
|
|
1540 | + * size = preferred_sizes[i].size;
|
|
1541 | + *
|
|
1542 | + * error = FT_Set_Pixel_Sizes( face, size, size );
|
|
1543 | + * <error handling omitted>
|
|
1544 | + *
|
|
1545 | + * // check whether we have a glyph in a bitmap strike
|
|
1546 | + * error = FT_Load_Glyph( face,
|
|
1547 | + * glyph_index,
|
|
1548 | + * FT_LOAD_SBITS_ONLY |
|
|
1549 | + * FT_LOAD_BITMAP_METRICS_ONLY )
|
|
1550 | + * if ( error == FT_Err_Invalid_Argument )
|
|
1551 | + * continue;
|
|
1552 | + * else if ( error )
|
|
1553 | + * <other error handling omitted>
|
|
1554 | + * else
|
|
1555 | + * break;
|
|
1556 | + * }
|
|
1557 | + *
|
|
1558 | + * if ( i == face->num_fixed_sizes )
|
|
1559 | + * <no embedded bitmap found, load outline glyph with
|
|
1560 | + * `FT_Load_Glyph`>
|
|
1561 | + * else
|
|
1562 | + * <load embedded bitmap with `FT_Load_Glyph`,
|
|
1563 | + * scale it, display it, etc.>
|
|
1564 | + * }
|
|
1565 | + * ```
|
|
1566 | + *
|
|
1567 | + * [*] Assuming a target value of 400dpi and available strike sizes 100,
|
|
1568 | + * 200, 300, and 400dpi, a possible order might be [400, 200, 300, 100]:
|
|
1569 | + * scaling 200dpi to 400dpi usually gives better results than scaling
|
|
1570 | + * 300dpi to 400dpi; it is also much faster. However, scaling 100dpi to
|
|
1571 | + * 400dpi can yield a too pixelated result, thus the preference might be
|
|
1572 | + * 300dpi over 100dpi.
|
|
1573 | + *
|
|
1574 | + * @since:
|
|
1575 | + * 2.12
|
|
1576 | + */
|
|
1577 | +#define FT_HAS_SBIX( face ) \
|
|
1578 | + ( !!( (face)->face_flags & FT_FACE_FLAG_SBIX ) )
|
|
1579 | + |
|
1580 | + |
|
1512 | 1581 | /**************************************************************************
|
1513 | 1582 | *
|
1514 | 1583 | * @enum:
|
... | ... | @@ -2976,6 +3045,15 @@ FT_BEGIN_HEADER |
2976 | 3045 | *
|
2977 | 3046 | * @FT_LOAD_NO_SCALE always sets this flag.
|
2978 | 3047 | *
|
3048 | + * FT_LOAD_SBITS_ONLY ::
|
|
3049 | + * [Since 2.12] This is the opposite of @FT_LOAD_NO_BITMAP, more or
|
|
3050 | + * less: @FT_Load_Glyph returns `FT_Err_Invalid_Argument` if the face
|
|
3051 | + * contains a bitmap strike for the given size (or the strike selected
|
|
3052 | + * by @FT_Select_Size) but there is no glyph in the strike.
|
|
3053 | + *
|
|
3054 | + * Note that this load flag was part of FreeType since version 2.0.6
|
|
3055 | + * but previously tagged as internal.
|
|
3056 | + *
|
|
2979 | 3057 | * FT_LOAD_VERTICAL_LAYOUT ::
|
2980 | 3058 | * Load the glyph for vertical text layout. In particular, the
|
2981 | 3059 | * `advance` value in the @FT_GlyphSlotRec structure is set to the
|
... | ... | @@ -3120,6 +3198,7 @@ FT_BEGIN_HEADER |
3120 | 3198 | #define FT_LOAD_IGNORE_TRANSFORM ( 1L << 11 )
|
3121 | 3199 | #define FT_LOAD_MONOCHROME ( 1L << 12 )
|
3122 | 3200 | #define FT_LOAD_LINEAR_DESIGN ( 1L << 13 )
|
3201 | +#define FT_LOAD_SBITS_ONLY ( 1L << 14 )
|
|
3123 | 3202 | #define FT_LOAD_NO_AUTOHINT ( 1L << 15 )
|
3124 | 3203 | /* Bits 16-19 are used by `FT_LOAD_TARGET_` */
|
3125 | 3204 | #define FT_LOAD_COLOR ( 1L << 20 )
|
... | ... | @@ -3130,7 +3209,6 @@ FT_BEGIN_HEADER |
3130 | 3209 | |
3131 | 3210 | /* used internally only by certain font drivers */
|
3132 | 3211 | #define FT_LOAD_ADVANCE_ONLY ( 1L << 8 )
|
3133 | -#define FT_LOAD_SBITS_ONLY ( 1L << 14 )
|
|
3134 | 3212 | #define FT_LOAD_SVG_ONLY ( 1L << 23 )
|
3135 | 3213 | |
3136 | 3214 | |
... | ... | @@ -3409,6 +3487,44 @@ FT_BEGIN_HEADER |
3409 | 3487 | * }
|
3410 | 3488 | *
|
3411 | 3489 | * ```
|
3490 | + *
|
|
3491 | + * FreeType has two rasterizers for generating SDF, namely:
|
|
3492 | + *
|
|
3493 | + * 1. `sdf` for generating SDF directly from glyph's outline, and
|
|
3494 | + *
|
|
3495 | + * 2. `bsdf` for generating SDF from rasterized bitmaps.
|
|
3496 | + *
|
|
3497 | + * Depending on the glyph type (i.e., outline or bitmap), one of the two
|
|
3498 | + * rasterizers is chosen at runtime and used for generating SDFs. To
|
|
3499 | + * force the use of `bsdf` you should render the glyph with any of the
|
|
3500 | + * FreeType's other rendering modes (e.g., `FT_RENDER_MODE_NORMAL`) and
|
|
3501 | + * then re-render with `FT_RENDER_MODE_SDF`.
|
|
3502 | + *
|
|
3503 | + * There are some issues with stability and possible failures of the SDF
|
|
3504 | + * renderers (specifically `sdf`).
|
|
3505 | + *
|
|
3506 | + * 1. The `sdf` rasterizer is sensitive to really small features (e.g.,
|
|
3507 | + * sharp turns that are less than 1~pixel) and imperfections in the
|
|
3508 | + * glyph's outline, causing artifacts in the final output.
|
|
3509 | + *
|
|
3510 | + * 2. The `sdf` rasterizer has limited support for handling intersecting
|
|
3511 | + * contours and *cannot* handle self-intersecting contours whatsoever.
|
|
3512 | + * Self-intersection happens when a single connected contour intersect
|
|
3513 | + * itself at some point; having these in your font definitely pose a
|
|
3514 | + * problem to the rasterizer and cause artifacts, too.
|
|
3515 | + *
|
|
3516 | + * 3. Generating SDF for really small glyphs may result in undesirable
|
|
3517 | + * output; the pixel grid (which stores distance information) becomes
|
|
3518 | + * too coarse.
|
|
3519 | + *
|
|
3520 | + * 4. Since the output buffer is normalized, precision at smaller spreads
|
|
3521 | + * is greater than precision at larger spread values because the
|
|
3522 | + * output range of [0..255] gets mapped to a smaller SDF range. A
|
|
3523 | + * spread of~2 should be sufficient in most cases.
|
|
3524 | + *
|
|
3525 | + * Points (1) and (2) can be avoided by using the `bsdf` rasterizer,
|
|
3526 | + * which is more stable than the `sdf` rasterizer in general.
|
|
3527 | + *
|
|
3412 | 3528 | */
|
3413 | 3529 | typedef enum FT_Render_Mode_
|
3414 | 3530 | {
|
... | ... | @@ -47,6 +47,9 @@ FT_BEGIN_HEADER |
47 | 47 | * MM fonts, others will work with all three types. They are similar
|
48 | 48 | * enough that a consistent interface makes sense.
|
49 | 49 | *
|
50 | + * For Adobe MM fonts, macro @FT_IS_SFNT returns false. For GX and
|
|
51 | + * OpenType variation fonts, it returns true.
|
|
52 | + *
|
|
50 | 53 | */
|
51 | 54 | |
52 | 55 |
... | ... | @@ -453,22 +453,22 @@ FT_BEGIN_HEADER |
453 | 453 | /**************************************************************************
|
454 | 454 | *
|
455 | 455 | * @function:
|
456 | - * FT_Has_PS_Glyph_Names
|
|
456 | + * FT_Has_PS_Glyph_Names
|
|
457 | 457 | *
|
458 | 458 | * @description:
|
459 | - * Return true if a given face provides reliable PostScript glyph names.
|
|
460 | - * This is similar to using the @FT_HAS_GLYPH_NAMES macro, except that
|
|
461 | - * certain fonts (mostly TrueType) contain incorrect glyph name tables.
|
|
459 | + * Return true if a given face provides reliable PostScript glyph names.
|
|
460 | + * This is similar to using the @FT_HAS_GLYPH_NAMES macro, except that
|
|
461 | + * certain fonts (mostly TrueType) contain incorrect glyph name tables.
|
|
462 | 462 | *
|
463 | - * When this function returns true, the caller is sure that the glyph
|
|
464 | - * names returned by @FT_Get_Glyph_Name are reliable.
|
|
463 | + * When this function returns true, the caller is sure that the glyph
|
|
464 | + * names returned by @FT_Get_Glyph_Name are reliable.
|
|
465 | 465 | *
|
466 | 466 | * @input:
|
467 | - * face ::
|
|
468 | - * face handle
|
|
467 | + * face ::
|
|
468 | + * face handle
|
|
469 | 469 | *
|
470 | 470 | * @return:
|
471 | - * Boolean. True if glyph names are reliable.
|
|
471 | + * Boolean. True if glyph names are reliable.
|
|
472 | 472 | *
|
473 | 473 | */
|
474 | 474 | FT_EXPORT( FT_Int )
|
... | ... | @@ -478,30 +478,40 @@ FT_BEGIN_HEADER |
478 | 478 | /**************************************************************************
|
479 | 479 | *
|
480 | 480 | * @function:
|
481 | - * FT_Get_PS_Font_Info
|
|
481 | + * FT_Get_PS_Font_Info
|
|
482 | 482 | *
|
483 | 483 | * @description:
|
484 | - * Retrieve the @PS_FontInfoRec structure corresponding to a given
|
|
485 | - * PostScript font.
|
|
484 | + * Retrieve the @PS_FontInfoRec structure corresponding to a given
|
|
485 | + * PostScript font.
|
|
486 | 486 | *
|
487 | 487 | * @input:
|
488 | - * face ::
|
|
489 | - * PostScript face handle.
|
|
488 | + * face ::
|
|
489 | + * PostScript face handle.
|
|
490 | 490 | *
|
491 | 491 | * @output:
|
492 | - * afont_info ::
|
|
493 | - * Output font info structure pointer.
|
|
492 | + * afont_info ::
|
|
493 | + * A pointer to a @PS_FontInfoRec object.
|
|
494 | 494 | *
|
495 | 495 | * @return:
|
496 | - * FreeType error code. 0~means success.
|
|
496 | + * FreeType error code. 0~means success.
|
|
497 | 497 | *
|
498 | 498 | * @note:
|
499 | - * String pointers within the @PS_FontInfoRec structure are owned by the
|
|
500 | - * face and don't need to be freed by the caller. Missing entries in
|
|
501 | - * the font's FontInfo dictionary are represented by `NULL` pointers.
|
|
499 | + * String pointers within the @PS_FontInfoRec structure are owned by the
|
|
500 | + * face and don't need to be freed by the caller. Missing entries in the
|
|
501 | + * font's FontInfo dictionary are represented by `NULL` pointers.
|
|
502 | + *
|
|
503 | + * The following font formats support this feature: 'Type~1', 'Type~42',
|
|
504 | + * 'CFF', 'CID~Type~1'. For other font formats this function returns the
|
|
505 | + * `FT_Err_Invalid_Argument` error code.
|
|
502 | 506 | *
|
503 | - * If the font's format is not PostScript-based, this function will
|
|
504 | - * return the `FT_Err_Invalid_Argument` error code.
|
|
507 | + * @example:
|
|
508 | + * ```
|
|
509 | + * PS_FontInfoRec font_info;
|
|
510 | + *
|
|
511 | + *
|
|
512 | + * error = FT_Get_PS_Font_Info( face, &font_info );
|
|
513 | + * ...
|
|
514 | + * ```
|
|
505 | 515 | *
|
506 | 516 | */
|
507 | 517 | FT_EXPORT( FT_Error )
|
... | ... | @@ -512,29 +522,39 @@ FT_BEGIN_HEADER |
512 | 522 | /**************************************************************************
|
513 | 523 | *
|
514 | 524 | * @function:
|
515 | - * FT_Get_PS_Font_Private
|
|
525 | + * FT_Get_PS_Font_Private
|
|
516 | 526 | *
|
517 | 527 | * @description:
|
518 | - * Retrieve the @PS_PrivateRec structure corresponding to a given
|
|
519 | - * PostScript font.
|
|
528 | + * Retrieve the @PS_PrivateRec structure corresponding to a given
|
|
529 | + * PostScript font.
|
|
520 | 530 | *
|
521 | 531 | * @input:
|
522 | - * face ::
|
|
523 | - * PostScript face handle.
|
|
532 | + * face ::
|
|
533 | + * PostScript face handle.
|
|
524 | 534 | *
|
525 | 535 | * @output:
|
526 | - * afont_private ::
|
|
527 | - * Output private dictionary structure pointer.
|
|
536 | + * afont_private ::
|
|
537 | + * A pointer to a @PS_PrivateRec object.
|
|
528 | 538 | *
|
529 | 539 | * @return:
|
530 | - * FreeType error code. 0~means success.
|
|
540 | + * FreeType error code. 0~means success.
|
|
531 | 541 | *
|
532 | 542 | * @note:
|
533 | - * The string pointers within the @PS_PrivateRec structure are owned by
|
|
534 | - * the face and don't need to be freed by the caller.
|
|
543 | + * The string pointers within the @PS_PrivateRec structure are owned by
|
|
544 | + * the face and don't need to be freed by the caller.
|
|
535 | 545 | *
|
536 | - * If the font's format is not PostScript-based, this function returns
|
|
537 | - * the `FT_Err_Invalid_Argument` error code.
|
|
546 | + * Only the 'Type~1' font format supports this feature. For other font
|
|
547 | + * formats this function returns the `FT_Err_Invalid_Argument` error
|
|
548 | + * code.
|
|
549 | + *
|
|
550 | + * @example:
|
|
551 | + * ```
|
|
552 | + * PS_PrivateRec font_private;
|
|
553 | + *
|
|
554 | + *
|
|
555 | + * error = FT_Get_PS_Font_Private( face, &font_private );
|
|
556 | + * ...
|
|
557 | + * ```
|
|
538 | 558 | *
|
539 | 559 | */
|
540 | 560 | FT_EXPORT( FT_Error )
|
... | ... | @@ -693,67 +713,67 @@ FT_BEGIN_HEADER |
693 | 713 | /**************************************************************************
|
694 | 714 | *
|
695 | 715 | * @function:
|
696 | - * FT_Get_PS_Font_Value
|
|
716 | + * FT_Get_PS_Font_Value
|
|
697 | 717 | *
|
698 | 718 | * @description:
|
699 | - * Retrieve the value for the supplied key from a PostScript font.
|
|
719 | + * Retrieve the value for the supplied key from a PostScript font.
|
|
700 | 720 | *
|
701 | 721 | * @input:
|
702 | - * face ::
|
|
703 | - * PostScript face handle.
|
|
722 | + * face ::
|
|
723 | + * PostScript face handle.
|
|
704 | 724 | *
|
705 | - * key ::
|
|
706 | - * An enumeration value representing the dictionary key to retrieve.
|
|
725 | + * key ::
|
|
726 | + * An enumeration value representing the dictionary key to retrieve.
|
|
707 | 727 | *
|
708 | - * idx ::
|
|
709 | - * For array values, this specifies the index to be returned.
|
|
728 | + * idx ::
|
|
729 | + * For array values, this specifies the index to be returned.
|
|
710 | 730 | *
|
711 | - * value ::
|
|
712 | - * A pointer to memory into which to write the value.
|
|
731 | + * value ::
|
|
732 | + * A pointer to memory into which to write the value.
|
|
713 | 733 | *
|
714 | - * valen_len ::
|
|
715 | - * The size, in bytes, of the memory supplied for the value.
|
|
734 | + * valen_len ::
|
|
735 | + * The size, in bytes, of the memory supplied for the value.
|
|
716 | 736 | *
|
717 | 737 | * @output:
|
718 | - * value ::
|
|
719 | - * The value matching the above key, if it exists.
|
|
738 | + * value ::
|
|
739 | + * The value matching the above key, if it exists.
|
|
720 | 740 | *
|
721 | 741 | * @return:
|
722 | - * The amount of memory (in bytes) required to hold the requested value
|
|
723 | - * (if it exists, -1 otherwise).
|
|
742 | + * The amount of memory (in bytes) required to hold the requested value
|
|
743 | + * (if it exists, -1 otherwise).
|
|
724 | 744 | *
|
725 | 745 | * @note:
|
726 | - * The values returned are not pointers into the internal structures of
|
|
727 | - * the face, but are 'fresh' copies, so that the memory containing them
|
|
728 | - * belongs to the calling application. This also enforces the
|
|
729 | - * 'read-only' nature of these values, i.e., this function cannot be
|
|
730 | - * used to manipulate the face.
|
|
746 | + * The values returned are not pointers into the internal structures of
|
|
747 | + * the face, but are 'fresh' copies, so that the memory containing them
|
|
748 | + * belongs to the calling application. This also enforces the
|
|
749 | + * 'read-only' nature of these values, i.e., this function cannot be
|
|
750 | + * used to manipulate the face.
|
|
731 | 751 | *
|
732 | - * `value` is a void pointer because the values returned can be of
|
|
733 | - * various types.
|
|
752 | + * `value` is a void pointer because the values returned can be of
|
|
753 | + * various types.
|
|
734 | 754 | *
|
735 | - * If either `value` is `NULL` or `value_len` is too small, just the
|
|
736 | - * required memory size for the requested entry is returned.
|
|
755 | + * If either `value` is `NULL` or `value_len` is too small, just the
|
|
756 | + * required memory size for the requested entry is returned.
|
|
737 | 757 | *
|
738 | - * The `idx` parameter is used, not only to retrieve elements of, for
|
|
739 | - * example, the FontMatrix or FontBBox, but also to retrieve name keys
|
|
740 | - * from the CharStrings dictionary, and the charstrings themselves. It
|
|
741 | - * is ignored for atomic values.
|
|
758 | + * The `idx` parameter is used, not only to retrieve elements of, for
|
|
759 | + * example, the FontMatrix or FontBBox, but also to retrieve name keys
|
|
760 | + * from the CharStrings dictionary, and the charstrings themselves. It
|
|
761 | + * is ignored for atomic values.
|
|
742 | 762 | *
|
743 | - * `PS_DICT_BLUE_SCALE` returns a value that is scaled up by 1000. To
|
|
744 | - * get the value as in the font stream, you need to divide by 65536000.0
|
|
745 | - * (to remove the FT_Fixed scale, and the x1000 scale).
|
|
763 | + * `PS_DICT_BLUE_SCALE` returns a value that is scaled up by 1000. To
|
|
764 | + * get the value as in the font stream, you need to divide by 65536000.0
|
|
765 | + * (to remove the FT_Fixed scale, and the x1000 scale).
|
|
746 | 766 | *
|
747 | - * IMPORTANT: Only key/value pairs read by the FreeType interpreter can
|
|
748 | - * be retrieved. So, for example, PostScript procedures such as NP, ND,
|
|
749 | - * and RD are not available. Arbitrary keys are, obviously, not be
|
|
750 | - * available either.
|
|
767 | + * IMPORTANT: Only key/value pairs read by the FreeType interpreter can
|
|
768 | + * be retrieved. So, for example, PostScript procedures such as NP, ND,
|
|
769 | + * and RD are not available. Arbitrary keys are, obviously, not be
|
|
770 | + * available either.
|
|
751 | 771 | *
|
752 | - * If the font's format is not PostScript-based, this function returns
|
|
753 | - * the `FT_Err_Invalid_Argument` error code.
|
|
772 | + * If the font's format is not PostScript-based, this function returns
|
|
773 | + * the `FT_Err_Invalid_Argument` error code.
|
|
754 | 774 | *
|
755 | 775 | * @since:
|
756 | - * 2.4.8
|
|
776 | + * 2.4.8
|
|
757 | 777 | *
|
758 | 778 | */
|
759 | 779 | FT_EXPORT( FT_Long )
|
... | ... | @@ -105,7 +105,7 @@ |
105 | 105 | /* Don't want warnings about our own use of deprecated functions. */
|
106 | 106 | #define FT_DEPRECATED_ATTRIBUTE
|
107 | 107 | |
108 | -#include FT_MAC_H
|
|
108 | +#include <freetype/ftmac.h>
|
|
109 | 109 | |
110 | 110 | #ifndef kATSOptionFlagsUnRestrictedScope /* since Mac OS X 10.1 */
|
111 | 111 | #define kATSOptionFlagsUnRestrictedScope kATSOptionFlagsDefault
|
... | ... | @@ -13,7 +13,7 @@ This code implements a BDF driver for the FreeType library, following the |
13 | 13 | Adobe Specification V 2.2. The specification of the BDF font format is
|
14 | 14 | available from Adobe's web site:
|
15 | 15 | |
16 | - https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5005.BDF_Spec.pdf
|
|
16 | + https://adobe-type-tools.github.io/font-tech-notes/pdfs/5005.BDF_Spec.pdf
|
|
17 | 17 | |
18 | 18 | Many good bitmap fonts in bdf format come with XFree86 (www.XFree86.org).
|
19 | 19 | They do not define vertical metrics, because the X Consortium BDF
|
... | ... | @@ -23,6 +23,10 @@ specification has removed them. |
23 | 23 | Encodings
|
24 | 24 | *********
|
25 | 25 | |
26 | +[This section is out of date, retained for historical reasons. BDF
|
|
27 | + properties can be retrieved with `FT_Get_BDF_Property`, character set ID
|
|
28 | + values with `FT_Get_BDF_Charset_ID`.]
|
|
29 | + |
|
26 | 30 | The variety of encodings that accompanies bdf fonts appears to encompass the
|
27 | 31 | small set defined in freetype.h. On the other hand, two properties that
|
28 | 32 | specify encoding and registry are usually defined in bdf fonts.
|
... | ... | @@ -1900,7 +1900,8 @@ |
1900 | 1900 | /* WeightVector */
|
1901 | 1901 | {
|
1902 | 1902 | FT_UInt idx;
|
1903 | - PS_Blend blend = decoder->blend;
|
|
1903 | + PS_Blend blend = decoder->blend;
|
|
1904 | + FT_UInt len_buildchar = decoder->len_buildchar;
|
|
1904 | 1905 | |
1905 | 1906 | |
1906 | 1907 | if ( arg_cnt != 1 || !blend )
|
... | ... | @@ -1908,14 +1909,15 @@ |
1908 | 1909 | |
1909 | 1910 | idx = (FT_UInt)cf2_stack_popInt( opStack );
|
1910 | 1911 | |
1911 | - if ( idx + blend->num_designs >
|
|
1912 | - decoder->len_buildchar )
|
|
1912 | + if ( len_buildchar < blend->num_designs ||
|
|
1913 | + len_buildchar - blend->num_designs < idx )
|
|
1913 | 1914 | goto Unexpected_OtherSubr;
|
1914 | 1915 | |
1915 | - ft_memcpy( &decoder->buildchar[idx],
|
|
1916 | - blend->weight_vector,
|
|
1917 | - blend->num_designs *
|
|
1918 | - sizeof ( blend->weight_vector[0] ) );
|
|
1916 | + if ( decoder->buildchar && blend->weight_vector )
|
|
1917 | + ft_memcpy( &decoder->buildchar[idx],
|
|
1918 | + blend->weight_vector,
|
|
1919 | + blend->num_designs *
|
|
1920 | + sizeof ( blend->weight_vector[0] ) );
|
|
1919 | 1921 | }
|
1920 | 1922 | break;
|
1921 | 1923 |
... | ... | @@ -1548,8 +1548,9 @@ |
1548 | 1548 | /* the accepted shift for strong points in fractional pixels */
|
1549 | 1549 | #define PSH_STRONG_THRESHOLD 32
|
1550 | 1550 | |
1551 | - /* the maximum shift value in font units */
|
|
1552 | -#define PSH_STRONG_THRESHOLD_MAXIMUM 30
|
|
1551 | + /* the maximum shift value in font units tuned to distinguish */
|
|
1552 | + /* between stems and serifs in URW+ font collection */
|
|
1553 | +#define PSH_STRONG_THRESHOLD_MAXIMUM 12
|
|
1553 | 1554 | |
1554 | 1555 | |
1555 | 1556 | /* find strong points in a glyph */
|
... | ... | @@ -63,16 +63,14 @@ |
63 | 63 | {
|
64 | 64 | FT_UInt old_max = table->max_hints;
|
65 | 65 | FT_UInt new_max = count;
|
66 | - FT_Error error = FT_Err_Ok;
|
|
66 | + FT_Error error;
|
|
67 | 67 | |
68 | 68 | |
69 | - if ( new_max > old_max )
|
|
70 | - {
|
|
71 | - /* try to grow the table */
|
|
72 | - new_max = FT_PAD_CEIL( new_max, 8 );
|
|
73 | - if ( !FT_RENEW_ARRAY( table->hints, old_max, new_max ) )
|
|
74 | - table->max_hints = new_max;
|
|
75 | - }
|
|
69 | + /* try to grow the table */
|
|
70 | + new_max = FT_PAD_CEIL( new_max, 8 );
|
|
71 | + if ( !FT_QRENEW_ARRAY( table->hints, old_max, new_max ) )
|
|
72 | + table->max_hints = new_max;
|
|
73 | + |
|
76 | 74 | return error;
|
77 | 75 | }
|
78 | 76 | |
... | ... | @@ -90,17 +88,14 @@ |
90 | 88 | count = table->num_hints;
|
91 | 89 | count++;
|
92 | 90 | |
93 | - if ( count >= table->max_hints )
|
|
91 | + if ( count > table->max_hints )
|
|
94 | 92 | {
|
95 | 93 | error = ps_hint_table_ensure( table, count, memory );
|
96 | 94 | if ( error )
|
97 | 95 | goto Exit;
|
98 | 96 | }
|
99 | 97 | |
100 | - hint = table->hints + count - 1;
|
|
101 | - hint->pos = 0;
|
|
102 | - hint->len = 0;
|
|
103 | - hint->flags = 0;
|
|
98 | + hint = table->hints + count - 1; /* initialized upstream */
|
|
104 | 99 | |
105 | 100 | table->num_hints = count;
|
106 | 101 | |
... | ... | @@ -136,14 +131,15 @@ |
136 | 131 | FT_UInt count,
|
137 | 132 | FT_Memory memory )
|
138 | 133 | {
|
139 | - FT_UInt old_max = ( mask->max_bits + 7 ) >> 3;
|
|
140 | - FT_UInt new_max = ( count + 7 ) >> 3;
|
|
134 | + FT_UInt old_max = mask->max_bits >> 3;
|
|
135 | + FT_UInt new_max = ( count + 7 ) >> 3;
|
|
141 | 136 | FT_Error error = FT_Err_Ok;
|
142 | 137 | |
143 | 138 | |
144 | 139 | if ( new_max > old_max )
|
145 | 140 | {
|
146 | 141 | new_max = FT_PAD_CEIL( new_max, 8 );
|
142 | + /* added bytes are zeroed here */
|
|
147 | 143 | if ( !FT_RENEW_ARRAY( mask->bytes, old_max, new_max ) )
|
148 | 144 | mask->max_bits = new_max * 8;
|
149 | 145 | }
|
... | ... | @@ -154,31 +150,15 @@ |
154 | 150 | /* test a bit value in a given mask */
|
155 | 151 | static FT_Int
|
156 | 152 | ps_mask_test_bit( PS_Mask mask,
|
157 | - FT_Int idx )
|
|
153 | + FT_UInt idx )
|
|
158 | 154 | {
|
159 | - if ( (FT_UInt)idx >= mask->num_bits )
|
|
155 | + if ( idx >= mask->num_bits )
|
|
160 | 156 | return 0;
|
161 | 157 | |
162 | 158 | return mask->bytes[idx >> 3] & ( 0x80 >> ( idx & 7 ) );
|
163 | 159 | }
|
164 | 160 | |
165 | 161 | |
166 | - /* clear a given bit */
|
|
167 | - static void
|
|
168 | - ps_mask_clear_bit( PS_Mask mask,
|
|
169 | - FT_UInt idx )
|
|
170 | - {
|
|
171 | - FT_Byte* p;
|
|
172 | - |
|
173 | - |
|
174 | - if ( idx >= mask->num_bits )
|
|
175 | - return;
|
|
176 | - |
|
177 | - p = mask->bytes + ( idx >> 3 );
|
|
178 | - p[0] = (FT_Byte)( p[0] & ~( 0x80 >> ( idx & 7 ) ) );
|
|
179 | - }
|
|
180 | - |
|
181 | - |
|
182 | 162 | /* set a given bit, possibly grow the mask */
|
183 | 163 | static FT_Error
|
184 | 164 | ps_mask_set_bit( PS_Mask mask,
|
... | ... | @@ -269,6 +249,10 @@ |
269 | 249 | mask = table->masks + count - 1;
|
270 | 250 | mask->num_bits = 0;
|
271 | 251 | mask->end_point = 0;
|
252 | + /* reused mask must be cleared */
|
|
253 | + if ( mask->max_bits )
|
|
254 | + FT_MEM_ZERO( mask->bytes, mask->max_bits >> 3 );
|
|
255 | + |
|
272 | 256 | table->num_masks = count;
|
273 | 257 | |
274 | 258 | Exit:
|
... | ... | @@ -426,7 +410,7 @@ |
426 | 410 | PS_Mask mask2 = table->masks + index2;
|
427 | 411 | FT_UInt count1 = mask1->num_bits;
|
428 | 412 | FT_UInt count2 = mask2->num_bits;
|
429 | - FT_Int delta;
|
|
413 | + FT_UInt delta;
|
|
430 | 414 | |
431 | 415 | |
432 | 416 | if ( count2 > 0 )
|
... | ... | @@ -437,15 +421,14 @@ |
437 | 421 | |
438 | 422 | |
439 | 423 | /* if "count2" is greater than "count1", we need to grow the */
|
440 | - /* first bitset, and clear the highest bits */
|
|
424 | + /* first bitset */
|
|
441 | 425 | if ( count2 > count1 )
|
442 | 426 | {
|
443 | 427 | error = ps_mask_ensure( mask1, count2, memory );
|
444 | 428 | if ( error )
|
445 | 429 | goto Exit;
|
446 | 430 | |
447 | - for ( pos = count1; pos < count2; pos++ )
|
|
448 | - ps_mask_clear_bit( mask1, pos );
|
|
431 | + mask1->num_bits = count2;
|
|
449 | 432 | }
|
450 | 433 | |
451 | 434 | /* merge (unite) the bitsets */
|
... | ... | @@ -467,7 +450,7 @@ |
467 | 450 | mask2->end_point = 0;
|
468 | 451 | |
469 | 452 | /* number of masks to move */
|
470 | - delta = (FT_Int)( table->num_masks - 1 - index2 );
|
|
453 | + delta = table->num_masks - 1 - index2;
|
|
471 | 454 | if ( delta > 0 )
|
472 | 455 | {
|
473 | 456 | /* move to end of table for reuse */
|
... | ... | @@ -476,7 +459,7 @@ |
476 | 459 | |
477 | 460 | ft_memmove( mask2,
|
478 | 461 | mask2 + 1,
|
479 | - (FT_UInt)delta * sizeof ( PS_MaskRec ) );
|
|
462 | + delta * sizeof ( PS_MaskRec ) );
|
|
480 | 463 | |
481 | 464 | mask2[delta] = dummy;
|
482 | 465 | }
|
... | ... | @@ -647,7 +630,7 @@ |
647 | 630 | FT_Int pos,
|
648 | 631 | FT_Int len,
|
649 | 632 | FT_Memory memory,
|
650 | - FT_Int *aindex )
|
|
633 | + FT_UInt *aindex )
|
|
651 | 634 | {
|
652 | 635 | FT_Error error = FT_Err_Ok;
|
653 | 636 | FT_UInt flags = 0;
|
... | ... | @@ -665,9 +648,6 @@ |
665 | 648 | len = 0;
|
666 | 649 | }
|
667 | 650 | |
668 | - if ( aindex )
|
|
669 | - *aindex = -1;
|
|
670 | - |
|
671 | 651 | /* now, lookup stem in the current hints table */
|
672 | 652 | {
|
673 | 653 | PS_Mask mask;
|
... | ... | @@ -704,7 +684,7 @@ |
704 | 684 | goto Exit;
|
705 | 685 | |
706 | 686 | if ( aindex )
|
707 | - *aindex = (FT_Int)idx;
|
|
687 | + *aindex = idx;
|
|
708 | 688 | }
|
709 | 689 | |
710 | 690 | Exit:
|
... | ... | @@ -715,9 +695,9 @@ |
715 | 695 | /* add a "hstem3/vstem3" counter to our dimension table */
|
716 | 696 | static FT_Error
|
717 | 697 | ps_dimension_add_counter( PS_Dimension dim,
|
718 | - FT_Int hint1,
|
|
719 | - FT_Int hint2,
|
|
720 | - FT_Int hint3,
|
|
698 | + FT_UInt hint1,
|
|
699 | + FT_UInt hint2,
|
|
700 | + FT_UInt hint3,
|
|
721 | 701 | FT_Memory memory )
|
722 | 702 | {
|
723 | 703 | FT_Error error = FT_Err_Ok;
|
... | ... | @@ -744,26 +724,17 @@ |
744 | 724 | }
|
745 | 725 | |
746 | 726 | /* now, set the bits for our hints in the counter mask */
|
747 | - if ( hint1 >= 0 )
|
|
748 | - {
|
|
749 | - error = ps_mask_set_bit( counter, (FT_UInt)hint1, memory );
|
|
750 | - if ( error )
|
|
751 | - goto Exit;
|
|
752 | - }
|
|
727 | + error = ps_mask_set_bit( counter, hint1, memory );
|
|
728 | + if ( error )
|
|
729 | + goto Exit;
|
|
753 | 730 | |
754 | - if ( hint2 >= 0 )
|
|
755 | - {
|
|
756 | - error = ps_mask_set_bit( counter, (FT_UInt)hint2, memory );
|
|
757 | - if ( error )
|
|
758 | - goto Exit;
|
|
759 | - }
|
|
731 | + error = ps_mask_set_bit( counter, hint2, memory );
|
|
732 | + if ( error )
|
|
733 | + goto Exit;
|
|
760 | 734 | |
761 | - if ( hint3 >= 0 )
|
|
762 | - {
|
|
763 | - error = ps_mask_set_bit( counter, (FT_UInt)hint3, memory );
|
|
764 | - if ( error )
|
|
765 | - goto Exit;
|
|
766 | - }
|
|
735 | + error = ps_mask_set_bit( counter, hint3, memory );
|
|
736 | + if ( error )
|
|
737 | + goto Exit;
|
|
767 | 738 | |
768 | 739 | Exit:
|
769 | 740 | return error;
|
... | ... | @@ -892,7 +863,7 @@ |
892 | 863 | PS_Dimension dim;
|
893 | 864 | FT_Memory memory = hints->memory;
|
894 | 865 | FT_Int count;
|
895 | - FT_Int idx[3];
|
|
866 | + FT_UInt idx[3];
|
|
896 | 867 | |
897 | 868 | |
898 | 869 | /* limit "dimension" to 0..1 */
|
... | ... | @@ -738,6 +738,18 @@ |
738 | 738 | |
739 | 739 | contour = shape->contours;
|
740 | 740 | |
741 | + /* If the control point coincides with any of the end points */
|
|
742 | + /* then it is a line and should be treated as one to avoid */
|
|
743 | + /* unnecessary complexity later in the algorithm. */
|
|
744 | + if ( ( contour->last_pos.x == control_1->x &&
|
|
745 | + contour->last_pos.y == control_1->y ) ||
|
|
746 | + ( control_1->x == to->x &&
|
|
747 | + control_1->y == to->y ) )
|
|
748 | + {
|
|
749 | + sdf_line_to( to, user );
|
|
750 | + goto Exit;
|
|
751 | + }
|
|
752 | + |
|
741 | 753 | FT_CALL( sdf_edge_new( memory, &edge ) );
|
742 | 754 | |
743 | 755 | edge->edge_type = SDF_EDGE_CONIC;
|
... | ... | @@ -764,9 +776,9 @@ |
764 | 776 | const FT_26D6_Vec* to,
|
765 | 777 | void* user )
|
766 | 778 | {
|
767 | - SDF_Shape* shape = ( SDF_Shape* )user;
|
|
768 | - SDF_Edge* edge = NULL;
|
|
769 | - SDF_Contour* contour = NULL;
|
|
779 | + SDF_Shape* shape = ( SDF_Shape* )user;
|
|
780 | + SDF_Edge* edge = NULL;
|
|
781 | + SDF_Contour* contour = NULL;
|
|
770 | 782 | |
771 | 783 | FT_Error error = FT_Err_Ok;
|
772 | 784 | FT_Memory memory = shape->memory;
|
... | ... | @@ -1137,23 +1149,38 @@ |
1137 | 1149 | FT_Int max_splits,
|
1138 | 1150 | SDF_Edge** out )
|
1139 | 1151 | {
|
1140 | - FT_Error error = FT_Err_Ok;
|
|
1141 | - FT_26D6_Vec cpos[7];
|
|
1142 | - SDF_Edge* left,* right;
|
|
1152 | + FT_Error error = FT_Err_Ok;
|
|
1153 | + FT_26D6_Vec cpos[7];
|
|
1154 | + SDF_Edge* left, *right;
|
|
1155 | + const FT_26D6 threshold = ONE_PIXEL / 4;
|
|
1143 | 1156 | |
1144 | 1157 | |
1145 | - if ( !memory || !out )
|
|
1158 | + if ( !memory || !out )
|
|
1146 | 1159 | {
|
1147 | 1160 | error = FT_THROW( Invalid_Argument );
|
1148 | 1161 | goto Exit;
|
1149 | 1162 | }
|
1150 | 1163 | |
1151 | - /* split the conic */
|
|
1164 | + /* split the cubic */
|
|
1152 | 1165 | cpos[0] = control_points[0];
|
1153 | 1166 | cpos[1] = control_points[1];
|
1154 | 1167 | cpos[2] = control_points[2];
|
1155 | 1168 | cpos[3] = control_points[3];
|
1156 | 1169 | |
1170 | + /* If the segment is flat enough we won't get any benefit by */
|
|
1171 | + /* splitting it further, so we can just stop splitting. */
|
|
1172 | + /* */
|
|
1173 | + /* Check the deviation of the Bezier curve and stop if it is */
|
|
1174 | + /* smaller than the pre-defined `threshold` value. */
|
|
1175 | + if ( FT_ABS( 2 * cpos[0].x - 3 * cpos[1].x + cpos[3].x ) < threshold &&
|
|
1176 | + FT_ABS( 2 * cpos[0].y - 3 * cpos[1].y + cpos[3].y ) < threshold &&
|
|
1177 | + FT_ABS( cpos[0].x - 3 * cpos[2].x + 2 * cpos[3].x ) < threshold &&
|
|
1178 | + FT_ABS( cpos[0].y - 3 * cpos[2].y + 2 * cpos[3].y ) < threshold )
|
|
1179 | + {
|
|
1180 | + split_cubic( cpos );
|
|
1181 | + goto Append;
|
|
1182 | + }
|
|
1183 | + |
|
1157 | 1184 | split_cubic( cpos );
|
1158 | 1185 | |
1159 | 1186 | /* If max number of splits is done */
|
... | ... | @@ -1250,13 +1277,32 @@ |
1250 | 1277 | /* Subdivide the curve and add it to the list. */
|
1251 | 1278 | {
|
1252 | 1279 | FT_26D6_Vec ctrls[3];
|
1280 | + FT_26D6 dx, dy;
|
|
1281 | + FT_UInt num_splits;
|
|
1253 | 1282 | |
1254 | 1283 | |
1255 | 1284 | ctrls[0] = edge->start_pos;
|
1256 | 1285 | ctrls[1] = edge->control_a;
|
1257 | 1286 | ctrls[2] = edge->end_pos;
|
1258 | 1287 | |
1259 | - error = split_sdf_conic( memory, ctrls, 32, &new_edges );
|
|
1288 | + dx = FT_ABS( ctrls[2].x + ctrls[0].x - 2 * ctrls[1].x );
|
|
1289 | + dy = FT_ABS( ctrls[2].y + ctrls[0].y - 2 * ctrls[1].y );
|
|
1290 | + if ( dx < dy )
|
|
1291 | + dx = dy;
|
|
1292 | + |
|
1293 | + /* Calculate the number of necessary bisections. Each */
|
|
1294 | + /* bisection causes a four-fold reduction of the deviation, */
|
|
1295 | + /* hence we bisect the Bezier curve until the deviation */
|
|
1296 | + /* becomes less than 1/8th of a pixel. For more details */
|
|
1297 | + /* check file `ftgrays.c`. */
|
|
1298 | + num_splits = 1;
|
|
1299 | + while ( dx > ONE_PIXEL / 8 )
|
|
1300 | + {
|
|
1301 | + dx >>= 2;
|
|
1302 | + num_splits <<= 1;
|
|
1303 | + }
|
|
1304 | + |
|
1305 | + error = split_sdf_conic( memory, ctrls, num_splits, &new_edges );
|
|
1260 | 1306 | }
|
1261 | 1307 | break;
|
1262 | 1308 | |
... | ... | @@ -3286,6 +3332,7 @@ |
3286 | 3332 | FT_26D6_Vec grid_point = zero_vector;
|
3287 | 3333 | SDF_Signed_Distance dist = max_sdf;
|
3288 | 3334 | FT_UInt index = 0;
|
3335 | + FT_16D16 diff = 0;
|
|
3289 | 3336 | |
3290 | 3337 | |
3291 | 3338 | if ( x < 0 || x >= width )
|
... | ... | @@ -3313,7 +3360,7 @@ |
3313 | 3360 | if ( dist.distance > sp_sq )
|
3314 | 3361 | continue;
|
3315 | 3362 | |
3316 | - /* square_root the values and fit in a 6.10 fixed-point */
|
|
3363 | + /* take the square root of the distance if required */
|
|
3317 | 3364 | if ( USE_SQUARED_DISTANCES )
|
3318 | 3365 | dist.distance = square_root( dist.distance );
|
3319 | 3366 | |
... | ... | @@ -3325,11 +3372,15 @@ |
3325 | 3372 | /* check whether the pixel is set or not */
|
3326 | 3373 | if ( dists[index].sign == 0 )
|
3327 | 3374 | dists[index] = dist;
|
3328 | - else if ( dists[index].distance > dist.distance )
|
|
3329 | - dists[index] = dist;
|
|
3330 | - else if ( FT_ABS( dists[index].distance - dist.distance )
|
|
3331 | - < CORNER_CHECK_EPSILON )
|
|
3332 | - dists[index] = resolve_corner( dists[index], dist );
|
|
3375 | + else
|
|
3376 | + {
|
|
3377 | + diff = FT_ABS( dists[index].distance - dist.distance );
|
|
3378 | + |
|
3379 | + if ( diff <= CORNER_CHECK_EPSILON )
|
|
3380 | + dists[index] = resolve_corner( dists[index], dist );
|
|
3381 | + else if ( dists[index].distance > dist.distance )
|
|
3382 | + dists[index] = dist;
|
|
3383 | + }
|
|
3333 | 3384 | }
|
3334 | 3385 | }
|
3335 | 3386 |
... | ... | @@ -48,6 +48,8 @@ FT_BEGIN_HEADER |
48 | 48 | #define MIN_SPREAD 2
|
49 | 49 | /* maximum spread supported by the renderer */
|
50 | 50 | #define MAX_SPREAD 32
|
51 | + /* pixel size in 26.6 */
|
|
52 | +#define ONE_PIXEL ( 1 << 6 )
|
|
51 | 53 | |
52 | 54 | |
53 | 55 | /**************************************************************************
|
... | ... | @@ -851,12 +851,6 @@ |
851 | 851 | is_apple_sbit = 0;
|
852 | 852 | is_apple_sbix = !face->goto_table( face, TTAG_sbix, stream, 0 );
|
853 | 853 | |
854 | - /* Apple 'sbix' color bitmaps are rendered scaled and then the 'glyf'
|
|
855 | - * outline rendered on top. We don't support that yet, so just ignore
|
|
856 | - * the 'glyf' outline and advertise it as a bitmap-only font. */
|
|
857 | - if ( is_apple_sbix )
|
|
858 | - has_outline = FALSE;
|
|
859 | - |
|
860 | 854 | /* if this font doesn't contain outlines, we try to load */
|
861 | 855 | /* a `bhed' table */
|
862 | 856 | if ( !has_outline && sfnt->load_bhed )
|
... | ... | @@ -1057,6 +1051,9 @@ |
1057 | 1051 | face->colr )
|
1058 | 1052 | flags |= FT_FACE_FLAG_COLOR; /* color glyphs */
|
1059 | 1053 | |
1054 | + if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX )
|
|
1055 | + flags |= FT_FACE_FLAG_SBIX; /* has 'sbix' embedded bitmaps */
|
|
1056 | + |
|
1060 | 1057 | if ( has_outline == TRUE )
|
1061 | 1058 | flags |= FT_FACE_FLAG_SCALABLE; /* scalable outlines */
|
1062 | 1059 |
... | ... | @@ -857,10 +857,10 @@ |
857 | 857 | |
858 | 858 | p = colr->clip_list;
|
859 | 859 | |
860 | - /* limit points to the first byte after the end of the color table. */
|
|
861 | - /* Thus, in subsequent limit checks below we need to check whether the */
|
|
862 | - /* read pointer is strictly greater than a position offset */
|
|
863 | - /* by certain field sizes to the left of that position. */
|
|
860 | + /* Limit points to the first byte after the end of the color table. */
|
|
861 | + /* Thus, in subsequent limit checks below we need to check whether the */
|
|
862 | + /* read pointer is strictly greater than a position offset by certain */
|
|
863 | + /* field sizes to the left of that position. */
|
|
864 | 864 | limit = (FT_Byte*)colr->table + colr->table_size;
|
865 | 865 | |
866 | 866 | /* Check whether we can extract one `uint8` and one `uint32`. */
|
... | ... | @@ -94,7 +94,7 @@ |
94 | 94 | |
95 | 95 | p_next = p;
|
96 | 96 | |
97 | - p += 2; /* skip version */
|
|
97 | + p += 2; /* skip version */
|
|
98 | 98 | length = FT_NEXT_USHORT( p );
|
99 | 99 | coverage = FT_NEXT_USHORT( p );
|
100 | 100 | |
... | ... | @@ -144,7 +144,7 @@ |
144 | 144 | |
145 | 145 | |
146 | 146 | cur_pair = FT_NEXT_ULONG( p );
|
147 | - if ( cur_pair <= old_pair )
|
|
147 | + if ( cur_pair < old_pair )
|
|
148 | 148 | break;
|
149 | 149 | |
150 | 150 | p += 2;
|
... | ... | @@ -187,8 +187,9 @@ |
187 | 187 | FT_UInt left_glyph,
|
188 | 188 | FT_UInt right_glyph )
|
189 | 189 | {
|
190 | - FT_Int result = 0;
|
|
191 | - FT_UInt count, mask;
|
|
190 | + FT_Int result = 0;
|
|
191 | + FT_UInt count, mask;
|
|
192 | + |
|
192 | 193 | FT_Byte* p = face->kern_table;
|
193 | 194 | FT_Byte* p_limit = p + face->kern_table_size;
|
194 | 195 |
... | ... | @@ -1587,7 +1587,7 @@ |
1587 | 1587 | tt_face_get_metrics( face, FALSE, glyph_index, &abearing, &aadvance );
|
1588 | 1588 | |
1589 | 1589 | metrics->horiBearingX = (FT_Short)originOffsetX;
|
1590 | - metrics->horiBearingY = (FT_Short)( -originOffsetY + metrics->height );
|
|
1590 | + metrics->horiBearingY = (FT_Short)( originOffsetY + metrics->height );
|
|
1591 | 1591 | metrics->horiAdvance = (FT_UShort)( aadvance *
|
1592 | 1592 | face->root.size->metrics.x_ppem /
|
1593 | 1593 | face->header.Units_Per_EM );
|
... | ... | @@ -39,11 +39,11 @@ |
39 | 39 | |
40 | 40 | |
41 | 41 | /* NOTE: These table sizes are given by the specification. */
|
42 | -#define SVG_TABLE_HEADER_SIZE 10U
|
|
43 | -#define SVG_DOCUMENT_RECORD_SIZE 12U
|
|
44 | -#define SVG_DOCUMENT_LIST_MINIMUM_SIZE 2U + SVG_DOCUMENT_RECORD_SIZE
|
|
45 | -#define SVG_MINIMUM_SIZE SVG_TABLE_HEADER_SIZE + \
|
|
46 | - SVG_DOCUMENT_LIST_MINIMUM_SIZE
|
|
42 | +#define SVG_TABLE_HEADER_SIZE (10U)
|
|
43 | +#define SVG_DOCUMENT_RECORD_SIZE (12U)
|
|
44 | +#define SVG_DOCUMENT_LIST_MINIMUM_SIZE (2U + SVG_DOCUMENT_RECORD_SIZE)
|
|
45 | +#define SVG_MINIMUM_SIZE (SVG_TABLE_HEADER_SIZE + \
|
|
46 | + SVG_DOCUMENT_LIST_MINIMUM_SIZE)
|
|
47 | 47 | |
48 | 48 | |
49 | 49 | typedef struct Svg_
|
... | ... | @@ -2899,6 +2899,9 @@ |
2899 | 2899 | {
|
2900 | 2900 | if ( FT_IS_SCALABLE( glyph->face ) )
|
2901 | 2901 | {
|
2902 | + TT_Face face = (TT_Face)glyph->face;
|
|
2903 | + |
|
2904 | + |
|
2902 | 2905 | /* for the bbox we need the header only */
|
2903 | 2906 | (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
|
2904 | 2907 | (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE );
|
... | ... | @@ -2906,6 +2909,27 @@ |
2906 | 2909 | glyph->linearHoriAdvance = loader.linear;
|
2907 | 2910 | glyph->linearVertAdvance = loader.vadvance;
|
2908 | 2911 | |
2912 | + /* bitmaps from the `sbix' table need special treatment: */
|
|
2913 | + /* if there is a glyph contour, the bitmap origin must be */
|
|
2914 | + /* shifted to be relative to the lower left corner of the */
|
|
2915 | + /* glyph bounding box, also taking the left-side bearing */
|
|
2916 | + /* (or top bearing) into account */
|
|
2917 | + if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX &&
|
|
2918 | + loader.n_contours > 0 )
|
|
2919 | + {
|
|
2920 | + FT_Int bitmap_left = loader.bbox.xMin;
|
|
2921 | + FT_Int bitmap_top = loader.bbox.yMin;
|
|
2922 | + |
|
2923 | + |
|
2924 | + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
|
|
2925 | + bitmap_top += loader.top_bearing;
|
|
2926 | + else
|
|
2927 | + bitmap_left += loader.left_bearing;
|
|
2928 | + |
|
2929 | + glyph->bitmap_left += FT_MulFix( bitmap_left, x_scale ) >> 6;
|
|
2930 | + glyph->bitmap_top += FT_MulFix( bitmap_top, y_scale ) >> 6;
|
|
2931 | + }
|
|
2932 | + |
|
2909 | 2933 | /* sanity checks: if `xxxAdvance' in the sbit metric */
|
2910 | 2934 | /* structure isn't set, use `linearXXXAdvance' */
|
2911 | 2935 | if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance )
|
... | ... | @@ -150,22 +150,13 @@ |
150 | 150 | }
|
151 | 151 | |
152 | 152 | |
153 | - static FT_Error
|
|
154 | - t42_ps_get_font_private( FT_Face face,
|
|
155 | - PS_PrivateRec* afont_private )
|
|
156 | - {
|
|
157 | - *afont_private = ((T42_Face)face)->type1.private_dict;
|
|
158 | - |
|
159 | - return FT_Err_Ok;
|
|
160 | - }
|
|
161 | - |
|
162 | - |
|
163 | 153 | static const FT_Service_PsInfoRec t42_service_ps_info =
|
164 | 154 | {
|
165 | 155 | (PS_GetFontInfoFunc) t42_ps_get_font_info, /* ps_get_font_info */
|
166 | 156 | (PS_GetFontExtraFunc) t42_ps_get_font_extra, /* ps_get_font_extra */
|
167 | 157 | (PS_HasGlyphNamesFunc) t42_ps_has_glyph_names, /* ps_has_glyph_names */
|
168 | - (PS_GetFontPrivateFunc)t42_ps_get_font_private, /* ps_get_font_private */
|
|
158 | + /* Type42 fonts don't have a Private dict */
|
|
159 | + (PS_GetFontPrivateFunc)NULL, /* ps_get_font_private */
|
|
169 | 160 | /* not implemented */
|
170 | 161 | (PS_GetFontValueFunc) NULL /* ps_get_font_value */
|
171 | 162 | };
|