@@ -638,7 +638,7 @@ function updateIconBoundingBoxes(input : {iconBBox: SymbolBoundingBox | null, ic
638638 iconOffset : [ number , number ] , baseIconRotate : number , layoutIconSize : number , sizes : Sizes , shapedIcon : PositionedIcon , imagePositions : ImagePositionMap , iconScaleFactor : number ,
639639 iconAnchor : SymbolAnchor ) {
640640
641- const { appearanceIconOffset, appearanceIconRotate, appearanceIconSize} = getAppearanceIconValues ( appearance , symbolLayer , feature , canonical , iconOffset , baseIconRotate , layoutIconSize , sizes ) ;
641+ const { appearanceIconOffset, appearanceIconRotate, appearanceIconSize} = getAppearanceIconValues ( appearance , symbolLayer , feature , canonical , iconOffset , baseIconRotate , layoutIconSize , sizes . iconScaleFactor ) ;
642642
643643 let appearanceShapedIcon : PositionedIcon | null = null ;
644644 let appearanceVerticallyShapedIcon : PositionedIcon | null = null ;
@@ -667,8 +667,8 @@ function updateIconBoundingBoxes(input : {iconBBox: SymbolBoundingBox | null, ic
667667 }
668668}
669669
670- function getAppearanceIconValues ( appearance : SymbolAppearance , symbolLayer : SymbolStyleLayer , feature : SymbolFeature ,
671- canonical : CanonicalTileID , iconOffset : [ number , number ] , baseIconRotate : number , layoutIconSize : number , sizes : Sizes ) {
670+ export function getAppearanceIconValues ( appearance : SymbolAppearance , symbolLayer : SymbolStyleLayer , feature : SymbolFeature ,
671+ canonical : CanonicalTileID , iconOffset : [ number , number ] , baseIconRotate : number , layoutIconSize : number , iconScaleFactor : number ) {
672672 const appearanceIconOffsetValue = appearance . hasProperty ( 'icon-offset' ) ?
673673 symbolLayer . getAppearanceValueAndResolveTokens ( appearance , 'icon-offset' , feature , canonical , [ ] ) :
674674 null ;
@@ -687,7 +687,7 @@ function getAppearanceIconValues(appearance: SymbolAppearance, symbolLayer: Symb
687687 symbolLayer . getAppearanceValueAndResolveTokens ( appearance , 'icon-size' , feature , canonical , [ ] ) :
688688 null ;
689689 const appearanceIconSize = ( typeof appearanceIconSizeValue === 'number' ) ?
690- appearanceIconSizeValue * sizes . iconScaleFactor :
690+ appearanceIconSizeValue * iconScaleFactor :
691691 layoutIconSize ;
692692
693693 return { appearanceIconOffset, appearanceIconRotate, appearanceIconSize} ;
@@ -724,7 +724,7 @@ function updateTextBoundingBoxes(input: {textBBox: SymbolBoundingBox | null, tex
724724 }
725725}
726726
727- function getAppearanceTextValues ( appearance : SymbolAppearance , symbolLayer : SymbolStyleLayer , feature : SymbolFeature ,
727+ export function getAppearanceTextValues ( appearance : SymbolAppearance , symbolLayer : SymbolStyleLayer , feature : SymbolFeature ,
728728 canonical : CanonicalTileID , textOffset : [ number , number ] , baseTextRotate : number , layoutTextSize : number ) {
729729 const appearanceTextOffsetValue = appearance . hasProperty ( 'text-offset' ) ?
730730 symbolLayer . getAppearanceValueAndResolveTokens ( appearance , 'text-offset' , feature , canonical , [ ] ) :
@@ -919,6 +919,12 @@ function fitIconsToText(bucket: SymbolBucket, shapedIcon: PositionedIcon | undef
919919 return { defaultShapedIcon, verticallyShapedIcon} ;
920920}
921921
922+ export function computeFontScale ( textSize : number , textScaleFactor : number ) {
923+ const glyphSize = ONE_EM ;
924+ const fontScale = textSize * textScaleFactor / glyphSize ;
925+ return fontScale ;
926+ }
927+
922928/**
923929 * Given a feature and its shaped text and icon data, add a 'symbol
924930 * instance' for each _possible_ placement of the symbol feature.
@@ -963,17 +969,19 @@ function addFeature(bucket: SymbolBucket,
963969 const layout = bucket . layers [ 0 ] . layout ;
964970
965971 const glyphSize = ONE_EM ;
966- const fontScale = layoutTextSize * sizes . textScaleFactor / glyphSize ;
972+ const fontScale = computeFontScale ( layoutTextSize , sizes . textScaleFactor ) ;
967973
968974 const defaultShaping = getDefaultHorizontalShaping ( shapedTextOrientations . horizontal ) || shapedTextOrientations . vertical ;
969975
970- // Store text shaping data for icon-text-fit appearance updates
971- if ( iconTextFit !== 'none' && bucket . appearanceFeatureData && feature . index < bucket . appearanceFeatureData . length ) {
972- const featureData = bucket . appearanceFeatureData [ feature . index ] ;
976+ // Store text shaping data for icon-text-fit and text appearance updates
977+ const hasTextAppearances = bucket . hasAnyAppearanceProperty ( [ 'text-size' , 'text-offset' , 'text-rotate' ] ) ;
978+ if ( ( iconTextFit !== 'none' || hasTextAppearances ) && bucket . appearanceFeatureData && bucket . featureToAppearanceIndex [ feature . index ] < bucket . appearanceFeatureData . length ) {
979+ const featureData = bucket . appearanceFeatureData [ bucket . featureToAppearanceIndex [ feature . index ] ] ;
973980 if ( featureData ) {
974981 featureData . textShaping = defaultShaping ;
975982 featureData . iconTextFitPadding = layout . get ( 'icon-text-fit-padding' ) . evaluate ( feature , { } , canonical ) ;
976983 featureData . fontScale = fontScale ;
984+ featureData . textScaleFactor = sizes . textScaleFactor ;
977985 }
978986 }
979987 const isGlobe = projection . name === 'globe' ;
@@ -1115,27 +1123,12 @@ function addTextVertices(bucket: SymbolBucket,
11151123 symbolInstanceIndex : number ,
11161124 brightness ?: number | null ) {
11171125 const glyphQuads = getGlyphQuads ( tileAnchor , shapedText , textOffset ,
1118- layer , textAlongLine , feature , imageMap , bucket . allowVerticalPlacement ) ;
1126+ layer , textAlongLine , feature , imageMap , bucket . allowVerticalPlacement , undefined ) ;
11191127
1120- const sizeData = bucket . textSizeData ;
1121- let textSizeData : number [ ] = null ;
1122-
1123- if ( sizeData . kind === 'source' ) {
1124- textSizeData = [
1125- SIZE_PACK_FACTOR * layer . layout . get ( 'text-size' ) . evaluate ( feature , { } , canonical ) * sizes . textScaleFactor
1126- ] ;
1127- if ( textSizeData [ 0 ] > MAX_PACKED_SIZE ) {
1128- warnOnce ( `${ bucket . layerIds [ 0 ] } : Value for "text-size" is >= ${ MAX_GLYPH_ICON_SIZE } . Reduce your "text-size".` ) ;
1129- }
1130- } else if ( sizeData . kind === 'composite' ) {
1131- textSizeData = [
1132- SIZE_PACK_FACTOR * sizes . compositeTextSizes [ 0 ] . evaluate ( feature , { } , canonical ) * sizes . textScaleFactor ,
1133- SIZE_PACK_FACTOR * sizes . compositeTextSizes [ 1 ] . evaluate ( feature , { } , canonical ) * sizes . textScaleFactor
1134- ] ;
1135- if ( textSizeData [ 0 ] > MAX_PACKED_SIZE || textSizeData [ 1 ] > MAX_PACKED_SIZE ) {
1136- warnOnce ( `${ bucket . layerIds [ 0 ] } : Value for "text-size" is >= ${ MAX_GLYPH_ICON_SIZE } . Reduce your "text-size".` ) ;
1137- }
1138- }
1128+ const evaluatedTextSize = layer . layout . get ( 'text-size' ) . evaluate ( feature , { } , canonical ) ;
1129+ const minZoomSize = sizes . compositeTextSizes ? sizes . compositeTextSizes [ 0 ] . evaluate ( feature , { } , canonical ) : 0 ;
1130+ const maxZoomSize = sizes . compositeTextSizes ? sizes . compositeTextSizes [ 1 ] . evaluate ( feature , { } , canonical ) : 0 ;
1131+ const textSizeData = getSizeDataFromKind ( bucket . layerIds [ 0 ] , bucket . textSizeData , evaluatedTextSize , sizes . textScaleFactor , minZoomSize , maxZoomSize ) ;
11391132
11401133 bucket . addSymbols (
11411134 bucket . text ,
@@ -1166,6 +1159,32 @@ function addTextVertices(bucket: SymbolBucket,
11661159 return glyphQuads . length * 4 ;
11671160}
11681161
1162+ export function getSizeDataFromKind ( layerId : string , inputSizeData : SizeData , evaluatedTextSize : number , textScaleFactor : number ,
1163+ minZoomSize : number , maxZoomSize : number
1164+ ) {
1165+ const sizeData = inputSizeData ;
1166+ let textSizeData : number [ ] = null ;
1167+
1168+ if ( sizeData . kind === 'source' ) {
1169+ textSizeData = [
1170+ SIZE_PACK_FACTOR * evaluatedTextSize * textScaleFactor
1171+ ] ;
1172+ if ( textSizeData [ 0 ] > MAX_PACKED_SIZE ) {
1173+ warnOnce ( `${ layerId } : Value for "text-size" is >= ${ MAX_GLYPH_ICON_SIZE } . Reduce your "text-size".` ) ;
1174+ }
1175+ } else if ( sizeData . kind === 'composite' ) {
1176+ textSizeData = [
1177+ SIZE_PACK_FACTOR * minZoomSize * textScaleFactor ,
1178+ SIZE_PACK_FACTOR * maxZoomSize * textScaleFactor
1179+ ] ;
1180+ if ( textSizeData [ 0 ] > MAX_PACKED_SIZE || textSizeData [ 1 ] > MAX_PACKED_SIZE ) {
1181+ warnOnce ( `${ layerId } : Value for "text-size" is >= ${ MAX_GLYPH_ICON_SIZE } . Reduce your "text-size".` ) ;
1182+ }
1183+ }
1184+
1185+ return textSizeData ;
1186+ }
1187+
11691188function getDefaultHorizontalShaping ( horizontalShaping : Partial < Record < TextJustify , Shaping > > ) : Shaping | null {
11701189 // We don't care which shaping we get because this is used for collision purposes
11711190 // and all the justifications have the same collision box
@@ -1345,7 +1364,6 @@ function addSymbol(bucket: SymbolBucket,
13451364 // For more info check `updateVariableAnchors` in `draw_symbol.js` .
13461365
13471366 if ( shapedIcon ) {
1348- const sizeData = bucket . iconSizeData ;
13491367 const iconRotate = layer . layout . get ( 'icon-rotate' ) . evaluate ( feature , { } , canonical ) ;
13501368 const iconQuads = getIconQuads ( shapedIcon , iconRotate , isSDFIcon , hasIconTextFit , sizes . iconScaleFactor ) ;
13511369 const verticalIconQuads = verticallyShapedIcon ? getIconQuads ( verticallyShapedIcon , iconRotate , isSDFIcon , hasIconTextFit , sizes . iconScaleFactor ) : undefined ;
@@ -1357,26 +1375,10 @@ function addSymbol(bucket: SymbolBucket,
13571375 hasIconTextFit ) ;
13581376 numIconVertices = maxQuadCount * 4 ;
13591377
1360- let iconSizeData = null ;
1361-
1362- if ( sizeData . kind === 'source' ) {
1363- iconSizeData = [
1364- SIZE_PACK_FACTOR * layer . layout . get ( 'icon-size' ) . evaluate ( feature , { } , canonical ) * sizes . iconScaleFactor
1365- ] ;
1366- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1367- if ( iconSizeData [ 0 ] > MAX_PACKED_SIZE ) {
1368- warnOnce ( `${ bucket . layerIds [ 0 ] } : Value for "icon-size" is >= ${ MAX_GLYPH_ICON_SIZE } . Reduce your "icon-size".` ) ;
1369- }
1370- } else if ( sizeData . kind === 'composite' ) {
1371- iconSizeData = [
1372- SIZE_PACK_FACTOR * sizes . compositeIconSizes [ 0 ] . evaluate ( feature , { } , canonical ) * sizes . iconScaleFactor ,
1373- SIZE_PACK_FACTOR * sizes . compositeIconSizes [ 1 ] . evaluate ( feature , { } , canonical ) * sizes . iconScaleFactor
1374- ] ;
1375- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1376- if ( iconSizeData [ 0 ] > MAX_PACKED_SIZE || iconSizeData [ 1 ] > MAX_PACKED_SIZE ) {
1377- warnOnce ( `${ bucket . layerIds [ 0 ] } : Value for "icon-size" is >= ${ MAX_GLYPH_ICON_SIZE } . Reduce your "icon-size".` ) ;
1378- }
1379- }
1378+ const evaluatedIconSize = layer . layout . get ( 'icon-size' ) . evaluate ( feature , { } , canonical ) ;
1379+ const minZoomSize = sizes . compositeIconSizes ? sizes . compositeIconSizes [ 0 ] . evaluate ( feature , { } , canonical ) : 0 ;
1380+ const maxZoomSize = sizes . compositeIconSizes ? sizes . compositeIconSizes [ 1 ] . evaluate ( feature , { } , canonical ) : 0 ;
1381+ const iconSizeData = getSizeDataFromKind ( bucket . layerIds [ 0 ] , bucket . iconSizeData , evaluatedIconSize , sizes . iconScaleFactor , minZoomSize , maxZoomSize ) ;
13801382
13811383 bucket . addSymbols (
13821384 bucket . icon ,
0 commit comments