Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions 3rdparty/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,8 @@

## FreeType
- [![Upstream](https://img.shields.io/gitlab/v/tag/freetype/freetype?label=Upstream)](https://gitlab.freedesktop.org/freetype/freetype)
- Version: 2.14.3-a6d4860 (Until Apr 12, 2026), with modifications:
- Version: 2.14.3-c39ca391 (Until May 13, 2026), with modifications:
- ftsystem.c: Use UTF-8 instead ACP for Windows paths
- hvfload.c: Fix glyph->metrics.height too-small(=4) issue
- License: BSD-style (The FreeType Project)

## Glad
Expand Down
6 changes: 4 additions & 2 deletions 3rdparty/freetype/devel/ftoption.h
Original file line number Diff line number Diff line change
Expand Up @@ -439,8 +439,10 @@ FT_BEGIN_HEADER

/**************************************************************************
*
* The size in bytes of the render pool used by the scan-line converter to
* do all of its work.
* The size in bytes of the stack render pool used by the scan-line
* converters. Use this option to limit the stack usage. The memory
* requirements are proportional to size and complexity of a given glyph.
* FreeType's rasterizers switch to dynamic allocations when necessary.
*/
#define FT_RENDER_POOL_SIZE 16384L

Expand Down
6 changes: 4 additions & 2 deletions 3rdparty/freetype/include/freetype/config/ftoption.h
Original file line number Diff line number Diff line change
Expand Up @@ -439,8 +439,10 @@ FT_BEGIN_HEADER

/**************************************************************************
*
* The size in bytes of the render pool used by the scan-line converter to
* do all of its work.
* The size in bytes of the stack render pool used by the scan-line
* converters. Use this option to limit the stack usage. The memory
* requirements are proportional to size and complexity of a given glyph.
* FreeType's rasterizers switch to dynamic allocations when necessary.
*/
#define FT_RENDER_POOL_SIZE 16384L

Expand Down
1 change: 1 addition & 0 deletions 3rdparty/freetype/include/freetype/ftmoderr.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@
FT_MODERRDEF( Winfonts, 0x1500, "Windows FON/FNT module" )
FT_MODERRDEF( GXvalid, 0x1600, "GX validation module" )
FT_MODERRDEF( Sdf, 0x1700, "Signed distance field raster module" )
FT_MODERRDEF( HVF, 0x1800, "HVF module" )


#ifdef FT_MODERR_END_LIST
Expand Down
2 changes: 0 additions & 2 deletions 3rdparty/freetype/include/freetype/fttypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
#include <freetype/ftsystem.h>
#include <freetype/ftimage.h>

#include <stddef.h>


FT_BEGIN_HEADER

Expand Down
261 changes: 111 additions & 150 deletions 3rdparty/freetype/src/base/ftbitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -776,18 +776,12 @@
FT_Bitmap source_bitmap;
const FT_Bitmap* source;

FT_Vector source_offset;
FT_Vector target_offset;

FT_Bool free_source_bitmap = 0;
FT_Bool free_target_bitmap_on_error = 0;

FT_Pos source_llx, source_lly, source_urx, source_ury;
FT_Pos target_llx, target_lly, target_urx, target_ury;
FT_Pos final_llx, final_lly, final_urx, final_ury;
FT_BBox sbx, tbx, fbx;

unsigned int final_rows, final_width;
long x, y;


if ( !library || !target || !source_ || !atarget_offset )
Expand All @@ -811,110 +805,32 @@
if ( !( source_->width && source_->rows ) )
return FT_Err_Ok; /* nothing to do */

/* assure integer pixel offsets */
source_offset.x = FT_PIX_FLOOR( source_offset_.x );
source_offset.y = FT_PIX_FLOOR( source_offset_.y );
target_offset.x = FT_PIX_FLOOR( atarget_offset->x );
target_offset.y = FT_PIX_FLOOR( atarget_offset->y );
/* get source bitmap dimensions assuming integer offsets */
sbx.xMin = ( source_offset_.x >> 6 );
sbx.yMin = ( source_offset_.y >> 6 ) - source_->rows;
sbx.xMax = ( source_offset_.x >> 6 ) + source_->width;
sbx.yMax = ( source_offset_.y >> 6 );

/* get source bitmap dimensions */
source_llx = source_offset.x;
if ( FT_LONG_MIN + (FT_Pos)( source_->rows << 6 ) + 64 > source_offset.y )
{
FT_TRACE5((
"FT_Bitmap_Blend: y coordinate overflow in source bitmap\n" ));
return FT_THROW( Invalid_Argument );
}
source_lly = source_offset.y - ( source_->rows << 6 );
FT_TRACE5(( "FT_Bitmap_Blend:\n" ));
FT_TRACE5(( " source bitmap: (%ld, %ld) -- (%ld, %ld); %u x %u\n",
sbx.xMin, sbx.yMin, sbx.xMax, sbx.yMax,
source_->width, source_->rows ));

if ( FT_LONG_MAX - (FT_Pos)( source_->width << 6 ) - 64 < source_llx )
/* sanity check */
if ( sbx.xMin > sbx.xMax || sbx.yMin > sbx.yMax ||
source_->width > 0x7FFFU || source_->rows > 0x7FFFU )
{
FT_TRACE5((
"FT_Bitmap_Blend: x coordinate overflow in source bitmap\n" ));
FT_TRACE5(( "FT_Bitmap_Blend: source dimension overflow\n" ));
return FT_THROW( Invalid_Argument );
}
source_urx = source_llx + ( source_->width << 6 );
source_ury = source_offset.y;

/* get target bitmap dimensions */
if ( target->width && target->rows )
{
target_llx = target_offset.x;
if ( FT_LONG_MIN + (FT_Pos)( target->rows << 6 ) > target_offset.y )
{
FT_TRACE5((
"FT_Bitmap_Blend: y coordinate overflow in target bitmap\n" ));
return FT_THROW( Invalid_Argument );
}
target_lly = target_offset.y - ( target->rows << 6 );

if ( FT_LONG_MAX - (FT_Pos)( target->width << 6 ) < target_llx )
{
FT_TRACE5((
"FT_Bitmap_Blend: x coordinate overflow in target bitmap\n" ));
return FT_THROW( Invalid_Argument );
}
target_urx = target_llx + ( target->width << 6 );
target_ury = target_offset.y;
}
else
if ( !target->width || !target->rows )
{
target_llx = FT_LONG_MAX;
target_lly = FT_LONG_MAX;
target_urx = FT_LONG_MIN;
target_ury = FT_LONG_MIN;
}

/* compute final bitmap dimensions */
final_llx = FT_MIN( source_llx, target_llx );
final_lly = FT_MIN( source_lly, target_lly );
final_urx = FT_MAX( source_urx, target_urx );
final_ury = FT_MAX( source_ury, target_ury );

final_width = ( final_urx - final_llx ) >> 6;
final_rows = ( final_ury - final_lly ) >> 6;

#ifdef FT_DEBUG_LEVEL_TRACE
FT_TRACE5(( "FT_Bitmap_Blend:\n" ));
FT_TRACE5(( " source bitmap: (%ld, %ld) -- (%ld, %ld); %u x %u\n",
source_llx / 64, source_lly / 64,
source_urx / 64, source_ury / 64,
source_->width, source_->rows ));

if ( target->width && target->rows )
FT_TRACE5(( " target bitmap: (%ld, %ld) -- (%ld, %ld); %u x %u\n",
target_llx / 64, target_lly / 64,
target_urx / 64, target_ury / 64,
target->width, target->rows ));
else
FT_TRACE5(( " target bitmap: empty\n" ));

if ( final_width && final_rows )
FT_TRACE5(( " final bitmap: (%ld, %ld) -- (%ld, %ld); %u x %u\n",
final_llx / 64, final_lly / 64,
final_urx / 64, final_ury / 64,
final_width, final_rows ));
else
FT_TRACE5(( " final bitmap: empty\n" ));
#endif /* FT_DEBUG_LEVEL_TRACE */

if ( !( final_width && final_rows ) )
return FT_Err_Ok; /* nothing to do */

/* for blending, set offset vector of final bitmap */
/* temporarily to (0,0) */
source_llx -= final_llx;
source_lly -= final_lly;

if ( target->width && target->rows )
{
target_llx -= final_llx;
target_lly -= final_lly;
}
final_width = source_->width;
final_rows = source_->rows;

/* set up target bitmap */
if ( target->pixel_mode == FT_PIXEL_MODE_NONE )
{
/* create new empty bitmap */
target->width = final_width;
target->rows = final_rows;
Expand All @@ -926,72 +842,116 @@
return error;

free_target_bitmap_on_error = 1;

fbx = sbx;
}
else if ( target->width != final_width ||
target->rows != final_rows )
else
{
/* adjust old bitmap to enlarged size */
int pitch, new_pitch;
/* get target bitmap dimensions assuming integer offsets */
tbx.xMin = ( atarget_offset->x >> 6 );
tbx.yMin = ( atarget_offset->y >> 6 ) - target->rows;
tbx.xMax = ( atarget_offset->x >> 6 ) + target->width;
tbx.yMax = ( atarget_offset->y >> 6 );

unsigned char* buffer = NULL;
FT_TRACE5(( " target bitmap: (%ld, %ld) -- (%ld, %ld); %u x %u\n",
tbx.xMin, tbx.yMin, tbx.xMax, tbx.yMax,
target->width, target->rows ));

/* sanity check */
if ( tbx.xMin > tbx.xMax || tbx.yMin > tbx.yMax )
{
FT_TRACE5(( "FT_Bitmap_Blend: targget dimension overflow\n" ));
return FT_THROW( Invalid_Argument );
}

pitch = target->pitch;
/* compute final bitmap dimensions */
fbx.xMin = FT_MIN( sbx.xMin, tbx.xMin );
fbx.yMin = FT_MIN( sbx.yMin, tbx.yMin );
fbx.xMax = FT_MAX( sbx.xMax, tbx.xMax );
fbx.yMax = FT_MAX( sbx.yMax, tbx.yMax );

if ( pitch < 0 )
pitch = -pitch;
/* sanity check */
if ( fbx.xMin < -0x10000 || fbx.xMax >= 0x10000 ||
fbx.yMin < -0x10000 || fbx.yMax >= 0x10000 )
{
FT_TRACE5(( "FT_Bitmap_Blend: final dimension overflow\n" ));
return FT_THROW( Invalid_Argument );
}

new_pitch = (int)final_width * 4;
final_width = fbx.xMax - fbx.xMin;
final_rows = fbx.yMax - fbx.yMin;

/* TODO: provide an in-buffer solution for large bitmaps */
/* to avoid allocation of a new buffer */
if ( FT_ALLOC_MULT( buffer, final_rows, new_pitch ) )
goto Error;
/* adjust target bitmap to enlarged size */
if ( target->width < final_width ||
target->rows < final_rows )
{
int pitch, new_pitch;

/* copy data to new buffer */
x = target_llx >> 6;
y = target_lly >> 6;
unsigned char* buffer = NULL;

/* the bitmap flow is from top to bottom, */
/* but y is measured from bottom to top */
if ( target->pitch < 0 )
{
/* XXX */
}
else
{
unsigned char* p =
target->buffer;
unsigned char* q =
buffer +
( final_rows - y - target->rows ) * new_pitch +
x * 4;
unsigned char* limit_p =
p + pitch * (int)target->rows;

pitch = target->pitch;

if ( pitch < 0 )
pitch = -pitch;

new_pitch = (int)final_width * 4;

/* TODO: provide an in-buffer solution for large bitmaps */
/* to avoid allocation of a new buffer */
if ( FT_ALLOC_MULT( buffer, final_rows, new_pitch ) )
goto Error;

/* copy data to new buffer */

while ( p < limit_p )
/* the bitmap flow is from top to bottom, */
/* but y is measured from bottom to top */
if ( target->pitch < 0 )
{
FT_MEM_COPY( q, p, pitch );
/* XXX */
}
else
{
FT_Pos x = tbx.xMin - fbx.xMin;
FT_Pos y = tbx.yMin - fbx.yMin;

unsigned char* p =
target->buffer;
unsigned char* q =
buffer +
( final_rows - y - target->rows ) * new_pitch +
x * 4;
unsigned char* limit_p =
p + pitch * (int)target->rows;


p += pitch;
q += new_pitch;
while ( p < limit_p )
{
FT_MEM_COPY( q, p, pitch );

p += pitch;
q += new_pitch;
}
}
}

FT_FREE( target->buffer );
FT_FREE( target->buffer );

target->width = final_width;
target->rows = final_rows;
target->width = final_width;
target->rows = final_rows;

if ( target->pitch < 0 )
target->pitch = -new_pitch;
else
target->pitch = new_pitch;
if ( target->pitch < 0 )
target->pitch = -new_pitch;
else
target->pitch = new_pitch;

target->buffer = buffer;
target->buffer = buffer;
}
}

FT_TRACE5(( " final bitmap: (%ld, %ld) -- (%ld, %ld); %u x %u\n",
fbx.xMin, fbx.yMin, fbx.xMax, fbx.yMax,
final_width, final_rows ));

/* adjust source bitmap if necessary */
if ( source_->pixel_mode != FT_PIXEL_MODE_GRAY )
{
Expand All @@ -1008,8 +968,6 @@

/* do blending; the code below returns pre-multiplied channels, */
/* similar to what FreeType gets from `CBDT' tables */
x = source_llx >> 6;
y = source_lly >> 6;

/* the bitmap flow is from top to bottom, */
/* but y is measured from bottom to top */
Expand All @@ -1019,6 +977,9 @@
}
else
{
FT_Pos x = sbx.xMin - fbx.xMin;
FT_Pos y = sbx.yMin - fbx.yMin;

unsigned char* p =
source->buffer;
unsigned char* q =
Expand Down Expand Up @@ -1064,8 +1025,8 @@
}
}

atarget_offset->x = final_llx;
atarget_offset->y = final_lly + ( final_rows << 6 );
atarget_offset->x = fbx.xMin * 64;
atarget_offset->y = fbx.yMax * 64;

Error:
if ( error && free_target_bitmap_on_error )
Expand Down
Loading
Loading