-
-
Notifications
You must be signed in to change notification settings - Fork 277
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixed an issue where font metrics were incorrect for monospaced fonts. #8886
Changes from all commits
88b7db7
bd329d2
a533c88
b588080
2cba7d5
9e3bdd4
b6b621f
5c499f4
fed7138
21e1ca4
bd0c72e
b0dab18
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -162,17 +162,19 @@ | |
:defold) | ||
:distance-field)) | ||
|
||
(defn- measure-line [glyphs text-tracking ^String line] | ||
(defn- measure-line [is-monospaced padding glyphs text-tracking ^String line] | ||
(let [w (transduce (comp | ||
(map #(:advance (glyphs (int %)) 0.0)) | ||
(interpose text-tracking)) | ||
+ | ||
0.0 | ||
line) | ||
len (.length line)] | ||
(if-let [last (get glyphs (and (pos? len) (int (.charAt line (dec len)))))] | ||
(- (+ w (:left-bearing last) (:width last)) (:advance last)) | ||
w))) | ||
(if is-monospaced | ||
(+ w padding) | ||
(if-let [last (get glyphs (and (pos? len) (int (.charAt line (dec len)))))] | ||
(- (+ w (:left-bearing last) (:width last)) (:advance last)) | ||
w)))) | ||
|
||
(defn- split-text [glyphs ^String text line-break? max-width text-tracking] | ||
(if line-break? | ||
|
@@ -274,7 +276,7 @@ | |
line-height (+ (:max-descent font-map) (:max-ascent font-map)) | ||
text-tracking (* line-height text-tracking) | ||
lines (split-text glyphs text line-break? max-width text-tracking) | ||
line-widths (map (partial measure-line glyphs text-tracking) lines) | ||
line-widths (map (partial measure-line (:is-monospaced font-map) (:padding font-map) glyphs text-tracking) lines) | ||
max-width (reduce max 0 line-widths)] | ||
[max-width (* line-height (+ 1 (* text-leading (dec (count lines)))))])))) | ||
|
||
|
@@ -301,7 +303,7 @@ | |
line-height (+ (:max-descent font-map) (:max-ascent font-map)) | ||
text-tracking (* line-height text-tracking) | ||
lines (split-text glyphs text line-break? max-width text-tracking) | ||
line-widths (mapv (partial measure-line glyphs text-tracking) lines) | ||
line-widths (mapv (partial measure-line (:is-monospaced font-map) (:padding font-map) glyphs text-tracking) lines) | ||
max-width (reduce max 0 line-widths)] | ||
(assoc text-layout | ||
:width max-width | ||
|
@@ -404,14 +406,20 @@ | |
face-mask (if layer-mask-enabled | ||
[1 0 0] | ||
[1 1 1]) | ||
shadow-offset {:x (:shadow-x font-map), :y (:shadow-y font-map)} | ||
shadow-offset {:x (if (:is-monospaced font-map) | ||
(- (:shadow-x font-map) (* (:padding font-map) 0.5)) | ||
(:shadow-x font-map)) | ||
:y (:shadow-y font-map)} | ||
alpha (:alpha font-map) | ||
outline-alpha (:outline-alpha font-map) | ||
shadow-alpha (:shadow-alpha font-map)] | ||
;; Output glyphs per layer in back to front, if enabled but always output face layer. | ||
shadow-alpha (:shadow-alpha font-map) | ||
font-offset {:x (if (:is-monospaced font-map) | ||
(- 0 (* (:padding font-map) 0.5)) | ||
0) | ||
:y 0}] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We render each glyph starting some point and then draw every next letter at Advance Width (+ tracking) from prev. one. But width of the glyph already include padding. Which makes width of the text a bit bigger and moves initial rendering point for the padding. Adding padding the line-widths helps to return real line width and compensate 0.5 of padding for the positioning . But another 0.5 of padding should be compensted by moving the initial point of rendering (we can't just add double padding to the line-width) |
||
(when (and layer-mask-enabled shadow-enabled) (fill-vertex-buffer-quads vbuf text-entries put-pos-uv-fn line-height char->glyph glyph-cache put-glyph-quad-fn [0 0 1] shadow-offset alpha outline-alpha shadow-alpha)) | ||
(when (and layer-mask-enabled outline-enabled) (fill-vertex-buffer-quads vbuf text-entries put-pos-uv-fn line-height char->glyph glyph-cache put-glyph-quad-fn [0 1 0] nil alpha outline-alpha shadow-alpha)) | ||
(fill-vertex-buffer-quads vbuf text-entries put-pos-uv-fn line-height char->glyph glyph-cache put-glyph-quad-fn face-mask nil alpha outline-alpha shadow-alpha))) | ||
(when (and layer-mask-enabled outline-enabled) (fill-vertex-buffer-quads vbuf text-entries put-pos-uv-fn line-height char->glyph glyph-cache put-glyph-quad-fn [0 1 0] font-offset alpha outline-alpha shadow-alpha)) | ||
(fill-vertex-buffer-quads vbuf text-entries put-pos-uv-fn line-height char->glyph glyph-cache put-glyph-quad-fn face-mask font-offset alpha outline-alpha shadow-alpha))) | ||
|
||
(defn gen-vertex-buffer | ||
[^GL2 gl {:keys [type font-map] :as font-data} text-entries] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -83,6 +83,8 @@ namespace dmRender | |
, m_CacheCellPadding(0) | ||
, m_LayerMask(FACE) | ||
, m_ImageFormat(dmRenderDDF::TYPE_BITMAP) | ||
, m_IsMonospaced(false) | ||
, m_Padding(0) | ||
{ | ||
|
||
} | ||
|
@@ -111,6 +113,8 @@ namespace dmRender | |
, m_CacheCellMaxAscent(0) | ||
, m_CacheCellPadding(0) | ||
, m_LayerMask(FACE) | ||
, m_IsMonospaced(false) | ||
, m_Padding(0) | ||
{ | ||
|
||
} | ||
|
@@ -162,6 +166,8 @@ namespace dmRender | |
uint32_t m_CacheCellMaxAscent; | ||
uint8_t m_CacheCellPadding; | ||
uint8_t m_LayerMask; | ||
uint8_t m_IsMonospaced:1; | ||
uint8_t m_Padding:7; | ||
}; | ||
|
||
static float GetLineTextMetrics(HFontMap font_map, float tracking, const char* text, int n, bool measure_trailing_space); | ||
|
@@ -235,6 +241,8 @@ namespace dmRender | |
uint32_t cell_count = font_map->m_CacheColumns * font_map->m_CacheRows; | ||
|
||
font_map->m_CellTempData = (uint8_t*)malloc(font_map->m_CacheCellWidth*font_map->m_CacheCellHeight*4); | ||
font_map->m_IsMonospaced = params.m_IsMonospaced; | ||
font_map->m_Padding = params.m_Padding; | ||
|
||
switch (params.m_GlyphChannels) | ||
{ | ||
|
@@ -325,6 +333,8 @@ namespace dmRender | |
font_map->m_OutlineAlpha = params.m_OutlineAlpha; | ||
font_map->m_ShadowAlpha = params.m_ShadowAlpha; | ||
font_map->m_LayerMask = params.m_LayerMask; | ||
font_map->m_IsMonospaced = params.m_IsMonospaced; | ||
font_map->m_Padding = params.m_Padding; | ||
|
||
font_map->m_CacheWidth = params.m_CacheWidth; | ||
font_map->m_CacheHeight = params.m_CacheHeight; | ||
|
@@ -515,7 +525,7 @@ namespace dmRender | |
center_x += metrics.m_Width/2; // move halfway to the right since we're aligning left | ||
break; | ||
case TEXT_ALIGN_RIGHT: | ||
center_x -= metrics.m_Height/2; // move halfway to the left from pivot since we're aligning right | ||
center_x -= metrics.m_Width/2; // move halfway to the left from pivot since we're aligning right | ||
break; | ||
// nothing to do for TEXT_ALIGN_CENTER. Pivot is already at the center of the text X-wise | ||
} | ||
|
@@ -739,6 +749,10 @@ namespace dmRender | |
float layout_width; | ||
int line_count = Layout(text, width, lines, max_lines, &layout_width, lm, measure_trailing_space); | ||
float x_offset = OffsetX(te.m_Align, te.m_Width); | ||
if (font_map->m_IsMonospaced) | ||
{ | ||
x_offset -= font_map->m_Padding * 0.5f; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please check the comment for clojure code. |
||
} | ||
float y_offset = OffsetY(te.m_VAlign, te.m_Height, font_map->m_MaxAscent, font_map->m_MaxDescent, te.m_Leading, line_count); | ||
|
||
const Vector4 face_color = dmGraphics::UnpackRGBA(te.m_FaceColor); | ||
|
@@ -835,8 +849,8 @@ namespace dmRender | |
|
||
for (int line = 0; line < line_count; ++line) { | ||
TextLine& l = lines[line]; | ||
int16_t x = (int16_t)(x_offset - OffsetX(te.m_Align, l.m_Width) + 0.5f); | ||
int16_t y = (int16_t) (y_offset - line * leading + 0.5f); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rounded vertex coordinates is the reason of dancing text (#7197) |
||
float x = x_offset - OffsetX(te.m_Align, l.m_Width); | ||
float y = y_offset - line * leading; | ||
const char* cursor = &text[l.m_Index]; | ||
int n = l.m_Count; | ||
for (int j = 0; j < n; ++j) | ||
|
@@ -1015,7 +1029,7 @@ namespace dmRender | |
vertexindex += vertices_per_quad; | ||
} | ||
} | ||
x += (int16_t)(g->m_Advance + tracking); | ||
x += g->m_Advance + tracking; | ||
} | ||
} | ||
|
||
|
@@ -1201,15 +1215,20 @@ namespace dmRender | |
} | ||
|
||
last = g; | ||
// NOTE: We round advance here just as above in DrawText | ||
width += (int16_t) (g->m_Advance + tracking); | ||
width += g->m_Advance + tracking; | ||
} | ||
if (n > 0 && 0 != last) | ||
{ | ||
uint32_t last_width = (measure_trailing_space && last->m_Character == ' ') ? (int16_t)last->m_Advance : last->m_Width; | ||
float last_end_point = last->m_LeftBearing + last_width; | ||
float last_right_bearing = last->m_Advance - last_end_point; | ||
width = width - last_right_bearing - tracking; | ||
if (font_map->m_IsMonospaced) { | ||
width += font_map->m_Padding; | ||
} | ||
else { | ||
uint32_t last_width = (measure_trailing_space && last->m_Character == ' ') ? last->m_Advance : last->m_Width; | ||
float last_end_point = last->m_LeftBearing + last_width; | ||
float last_right_bearing = last->m_Advance - last_end_point; | ||
width = width - last_right_bearing; | ||
} | ||
width -= tracking; | ||
} | ||
|
||
return width; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For non-monospaced fonts, this value taken into account as part of the last glyph width (we add padding*2 to each width). But for monospaced fonts, we need it to add it as part of the text width and also to offset it back when rendering monospaced font.