@@ -442,51 +442,70 @@ function buildDrawGlyph(drawStr, charCode) {
442442 return new opentype . Glyph ( { name : `draw_${ charCode } ` , unicode : charCode , advanceWidth : EM , path } ) ;
443443}
444444function buildDrawingFont ( uniqueDrawingsArray , existingFontBuffer , referencedCharsArray , id ) {
445+ const referencedCharsSet = new Set ( referencedCharsArray ) ;
446+
447+ if ( uniqueDrawingsArray . length === 0 && existingFontBuffer && existingFontBuffer . byteLength > 0 ) {
448+ try {
449+ const existingFont = opentype . parse ( existingFontBuffer ) ;
450+ const existingChars = new Set ( ) ;
451+ for ( let i = 1 ; i < existingFont . glyphs . length ; i ++ ) {
452+ const g = existingFont . glyphs . get ( i ) ;
453+ if ( g && g . unicode && g . unicode > 0 ) existingChars . add ( String . fromCodePoint ( g . unicode ) ) ;
454+ }
455+ const sameChars = existingChars . size === referencedCharsSet . size &&
456+ [ ...referencedCharsSet ] . every ( ch => existingChars . has ( ch ) ) ;
457+ if ( sameChars ) {
458+ return {
459+ ttf : new Uint8Array ( existingFontBuffer ) ,
460+ dataToCharArr : [ ]
461+ } ;
462+ }
463+ } catch ( _ ) { }
464+ }
465+
445466 const notdef = new opentype . Glyph ( {
446467 name : '.notdef' , unicode : 0 , advanceWidth : EM , path : new opentype . Path ( )
447468 } ) ;
448469 const glyphs = [ notdef ] ;
449- const charToData = new Map ( ) ;
450- const dataToChar = new Map ( ) ;
451- const nextChar = ( idx ) => getVisibleChar ( idx ) ;
470+ const existingCharToGlyph = new Map ( ) ;
452471
453472 if ( existingFontBuffer && existingFontBuffer . byteLength > 0 ) {
454473 try {
455474 const existingFont = opentype . parse ( existingFontBuffer ) ;
456- const usedChars = new Set ( referencedCharsArray ) ;
457- for ( const ch of usedChars ) {
458- const glyph = existingFont . charToGlyph ( ch ) ;
459- if ( glyph && glyph . index !== 0 ) {
460- const path = existingFont . getPath ( ch , 0 , 0 , existingFont . unitsPerEm ) ;
461- const drawStr = path . toPathData ( ) ;
462- charToData . set ( ch , drawStr ) ;
463- dataToChar . set ( drawStr , ch ) ;
464- }
475+ for ( let i = 1 ; i < existingFont . glyphs . length ; i ++ ) {
476+ const g = existingFont . glyphs . get ( i ) ;
477+ if ( ! g || ! g . unicode || g . unicode === 0 ) continue ;
478+ const ch = String . fromCodePoint ( g . unicode ) ;
479+ if ( ! referencedCharsSet . has ( ch ) ) continue ;
480+ existingCharToGlyph . set ( ch , g ) ;
481+ glyphs . push ( new opentype . Glyph ( {
482+ name : g . name || `draw_${ g . unicode } ` ,
483+ unicode : g . unicode ,
484+ advanceWidth : g . advanceWidth || EM ,
485+ path : g . path
486+ } ) ) ;
465487 }
466488 } catch ( _ ) { }
467489 }
468490
469491 const drawingDataToChar = { } ;
470- const currentSafeIndex = { val : 0 } ;
492+
493+ const usedCodepoints = new Set ( glyphs . filter ( g => g . unicode > 0 ) . map ( g => g . unicode ) ) ;
494+ let safeIdx = 0 ;
471495 const getNextSafeChar = ( ) => {
472496 while ( true ) {
473- const c = nextChar ( currentSafeIndex . val ++ ) ;
474- if ( ! charToData . has ( c ) ) return c ;
497+ const c = getVisibleChar ( safeIdx ++ ) ;
498+ if ( ! usedCodepoints . has ( c . codePointAt ( 0 ) ) ) return c ;
475499 }
476500 } ;
477501
478502 const sortedSubsets = Array . from ( uniqueDrawingsArray ) . sort ( ( a , b ) => a . data . localeCompare ( b . data ) ) ;
479503 for ( const item of sortedSubsets ) {
480504 const data = item . data ;
481- const tempGlyph = buildDrawGlyph ( data , 0 ) ;
482- const normalizedData = tempGlyph . path . toPathData ( ) ;
483-
484- let char = dataToChar . get ( normalizedData ) ;
485- if ( ! char ) {
486- char = getNextSafeChar ( ) ;
487- }
488- drawingDataToChar [ data ] = char ;
489- const cp = char . codePointAt ( 0 ) ;
505+ const assignedChar = getNextSafeChar ( ) ;
506+ drawingDataToChar [ data ] = assignedChar ;
507+ const cp = assignedChar . codePointAt ( 0 ) ;
508+ usedCodepoints . add ( cp ) ;
490509 glyphs . push ( buildDrawGlyph ( data , cp ) ) ;
491510 }
492511
@@ -503,6 +522,8 @@ function buildDrawingFont(uniqueDrawingsArray, existingFontBuffer, referencedCha
503522 dataToCharArr : Object . entries ( drawingDataToChar ) . map ( ( [ d , c ] ) => ( { data : d , char : c } ) )
504523 } ;
505524}
525+
526+
506527function extractFontNames ( fontObj ) {
507528 const names = new Set ( ) ;
508529 const raw = fontObj . tables ?. name ?. names ;
@@ -816,7 +837,8 @@ function doConvert(data, id) {
816837 if ( options . wantDraw ) {
817838 const newDrawings = parsed . uniqueDrawings ;
818839 const totalDrawings = newDrawings . length ;
819- if ( totalDrawings > 0 || parsed . hasExistingDrawSubset ) {
840+ const hasReferencedChars = parsed . subsetReferencedChars . length > 0 ;
841+ if ( totalDrawings > 0 || ( parsed . hasExistingDrawSubset && hasReferencedChars ) ) {
820842 emitLog ( id , 'log.draw.building' , 'info' , {
821843 unique : totalDrawings , total : parsed . drawings
822844 } ) ;
0 commit comments