Skip to content

Commit bfb3892

Browse files
author
Fraser J. Gordon
committed
[[ Bugfix 12612 ]] Change block layout to use floating-point
Conflicts: engine/src/MCBlock.h engine/src/block.cpp engine/src/context.h engine/src/font.cpp engine/src/font.h engine/src/graphicscontext.cpp engine/src/graphicscontext.h engine/src/line.cpp engine/src/line.h engine/src/metacontext.cpp engine/src/metacontext.h engine/src/paragraf.cpp engine/src/paragraf.h
1 parent 62bb2db commit bfb3892

20 files changed

Lines changed: 142 additions & 144 deletions

engine/src/MCBlock.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ class MCBlock : public MCDLlist
6161
uint4 flags;
6262
Blockatts *atts;
6363
findex_t m_index, m_size;
64-
uint2 width;
65-
uint2 origin;
64+
coord_t width;
65+
coord_t origin;
6666
uint2 opened;
67-
uint2 tabpos; // Pixel offset to use when calculating tabstops
67+
coord_t tabpos; // Pixel offset to use when calculating tabstops
6868
uint2 visual_index; // Visual ordering index from left to right
6969
uint8_t direction_level;
7070

@@ -103,13 +103,13 @@ class MCBlock : public MCDLlist
103103
// 'flagged' are excluded from the sameness check (used by styledText).
104104
Boolean sameatts(MCBlock *bptr, bool p_persistent_only);
105105

106-
bool fit(int2 x, uint2 width, findex_t& r_break_index, bool& r_break_fits);
106+
bool fit(coord_t x, coord_t width, findex_t& r_break_index, bool& r_break_fits);
107107
void split(findex_t p_index);
108-
void drawstring(MCDC *dc, int2 x, int2 cx, int2 y, findex_t start, findex_t length, Boolean image, uint32_t style);
108+
void drawstring(MCDC *dc, coord_t x, coord_t cx, int2 y, findex_t start, findex_t length, Boolean image, uint32_t style);
109109

110110
// MW-2012-02-27: [[ Bug 2939 ]] The 'flags' parameter indicates whether the left and/or
111111
// right edge of any box or 3d-box should be rendered.
112-
void draw(MCDC *dc, int2 x, int2 cx, int2 y, findex_t si, findex_t ei, MCStringRef p_text, uint2 pstyle, uint32_t flags);
112+
void draw(MCDC *dc, coord_t x, coord_t cx, int2 y, findex_t si, findex_t ei, MCStringRef p_text, uint2 pstyle, uint32_t flags);
113113

114114
// MW-2012-02-17: [[ SplitTextAttrs ]] Returns the effective font attrs of the block.
115115
// If 'base_attrs' is non-nil, it uses that to derive the attrs.
@@ -160,8 +160,8 @@ class MCBlock : public MCDLlist
160160
parent = pgptr;
161161
}
162162

163-
uint2 getsubwidth(MCDC *dc, int2 x, findex_t i, findex_t l);
164-
uint2 getwidth(MCDC *dc, int2 x);
163+
coord_t getsubwidth(MCDC *dc, coord_t x, findex_t i, findex_t l);
164+
coord_t getwidth(MCDC *dc, coord_t x);
165165
void reset();
166166
uint2 getascent(void);
167167
uint2 getdescent(void);
@@ -259,12 +259,12 @@ class MCBlock : public MCDLlist
259259

260260
////////// BIDIRECTIONAL SUPPORT
261261

262-
uint2 getorigin() const
262+
coord_t getorigin() const
263263
{
264264
return origin;
265265
}
266266

267-
void setorigin(uint2 o)
267+
void setorigin(coord_t o)
268268
{
269269
origin = o;
270270
}
@@ -295,15 +295,15 @@ class MCBlock : public MCDLlist
295295
return GetDirectionLevel() & 1;
296296
}
297297

298-
uint2 getwidth(MCDC *dc = NULL)
298+
coord_t getwidth(MCDC *dc = NULL)
299299
{
300300
if (is_rtl())
301301
return getwidth(dc, origin - width);
302302
else
303303
return getwidth(dc, origin);
304304
}
305305

306-
void settabpos(uint2 offset)
306+
void settabpos(coord_t offset)
307307
{
308308
tabpos = offset;
309309
}
@@ -330,10 +330,10 @@ class MCBlock : public MCDLlist
330330
void MoveRange(findex_t t_index_offset, findex_t t_length_offset);
331331

332332
// Translates from a pixel position to a cursor index
333-
findex_t GetCursorIndex(int2 x, Boolean chunk, Boolean last);
333+
findex_t GetCursorIndex(coord_t x, Boolean chunk, Boolean last);
334334

335335
// Returns the x coordinate of the cursor
336-
uint2 GetCursorX(findex_t fi);
336+
coord_t GetCursorX(findex_t fi);
337337

338338
// Moves the index forwards by one codepoint, possibly changing block
339339
MCBlock *AdvanceIndex(findex_t &x_index);

engine/src/block.cpp

Lines changed: 31 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,7 @@ static bool MCUnicodeCanBreakBetween(uint2 x, uint2 y)
652652
return !t_prohibit_break_after_x && !t_prohibit_break_before_y;
653653
}
654654

655-
bool MCBlock::fit(int2 x, uint2 maxwidth, findex_t& r_break_index, bool& r_break_fits)
655+
bool MCBlock::fit(coord_t x, coord_t maxwidth, findex_t& r_break_index, bool& r_break_fits)
656656
{
657657
// If the block of zero length, then it can't be broken and must be kept with previous blocks.
658658
if (m_size == 0)
@@ -700,10 +700,8 @@ bool MCBlock::fit(int2 x, uint2 maxwidth, findex_t& r_break_index, bool& r_break
700700
// but use the integer width to break. This ensures measure(a & b) == measure(a) + measure(b)
701701
// (otherwise you get drift as the accumulated width the block calculates is different
702702
// from the width of the text that is drawn).
703-
MCGFloat twidth_float;
704-
twidth_float = 0;
705-
int32_t twidth;
706-
twidth = 0;
703+
coord_t t_width;
704+
t_width = 0;
707705

708706
// MW-2009-04-23: [[ Bug ]] For printing, we measure complete runs of text otherwise we get
709707
// positioning issues.
@@ -779,23 +777,22 @@ bool MCBlock::fit(int2 x, uint2 maxwidth, findex_t& r_break_index, bool& r_break
779777
MCRange t_range;
780778
t_range = MCRangeMake(initial_i, i - initial_i);
781779
// MM-2014-04-16: [[ Bug 11964 ]] Pass through the transform of the stack to make sure the measurment is correct for scaled text.
782-
twidth_float += MCFontMeasureTextSubstringFloat(m_font, parent->GetInternalStringRef(), t_range, parent -> getparent() -> getstack() -> getdevicetransform());
783-
twidth = (int32_t)floorf(twidth_float);
780+
t_width += MCFontMeasureTextSubstringFloat(m_font, parent->GetInternalStringRef(), t_range, parent -> getparent() -> getstack() -> getdevicetransform());
784781
}
785782

786-
if (t_can_fit && twidth > maxwidth)
783+
if (t_can_fit && t_width > maxwidth)
787784
break;
788785

789786
if (t_can_break)
790787
t_break_index = i;
791788

792-
if (twidth <= maxwidth)
789+
if (t_width <= maxwidth)
793790
{
794791
t_can_fit = true;
795792
t_whole_block = t_end_of_block;
796793
}
797794

798-
if (twidth >= maxwidth)
795+
if (t_width >= maxwidth)
799796
break;
800797
}
801798

@@ -830,7 +827,7 @@ void MCBlock::split(findex_t p_index)
830827

831828
// Compute the distance between x and the next tab stop position.
832829
// FG-2014-04-30: [[ TabAlignments ]] Blocks no longer contain tabs
833-
/*int2 MCBlock::gettabwidth(int2 x, findex_t i)
830+
/*coord_t MCBlock::gettabwidth(coord_t x, findex_t i)
834831
{
835832
uint2 *tabs;
836833
uint2 ntabs;
@@ -944,7 +941,7 @@ void MCBlock::split(findex_t p_index)
944941
}
945942
}*/
946943

947-
void MCBlock::drawstring(MCDC *dc, int2 x, int2 p_cell_right, int2 y, findex_t start, findex_t length, Boolean image, uint32_t style)
944+
void MCBlock::drawstring(MCDC *dc, coord_t x, coord_t p_cell_right, int2 y, findex_t start, findex_t length, Boolean image, uint32_t style)
948945
{
949946
// MW-2012-02-16: [[ FontRefs ]] Fetch the font metrics we need to draw.
950947
int32_t t_ascent, t_descent;
@@ -985,19 +982,18 @@ void MCBlock::drawstring(MCDC *dc, int2 x, int2 p_cell_right, int2 y, findex_t s
985982
else
986983
t_next_index = t_next_tab;
987984

988-
int2 t_tab_width;
989-
t_tab_width = 64; //gettabwidth(0, t_index);
985+
//int2 t_tab_width;
986+
//t_tab_width = 64; //gettabwidth(0, t_index);
990987

991988
// MM-2014-04-16: [[ Bug 11964 ]] Pass through the transform of the stack to make sure the measurment is correct for scaled text.
992-
uint2 t_width;
989+
coord_t t_width;
993990
MCRange t_range;
994991
t_range = MCRangeMake(t_index, t_next_index - t_index);
995-
t_width = MCFontMeasureTextSubstring(m_font, parent->GetInternalStringRef(), t_range, parent -> getparent() -> getstack() -> getdevicetransform());
996-
992+
t_width = MCFontMeasureTextSubstringFloat(m_font, parent->GetInternalStringRef(), t_range, parent -> getparent() -> getstack() -> getdevicetransform());
997993

998994
// MW-2012-02-09: [[ ParaStyles ]] Compute the cell clip, taking into account padding.
999995
t_cell_clip . x = x - 1;
1000-
t_cell_clip . width = MCU_max(p_cell_right - x - t_padding * 2, 0);
996+
t_cell_clip . width = MCU_max(p_cell_right - x - t_padding * 2, 0.0f);
1001997

1002998
t_cell_clip = MCU_intersect_rect(t_cell_clip, t_old_clip);
1003999
dc -> setclip(t_cell_clip);
@@ -1072,10 +1068,10 @@ void MCBlock::drawstring(MCDC *dc, int2 x, int2 p_cell_right, int2 y, findex_t s
10721068
break;
10731069
10741070
// MM-2014-04-16: [[ Bug 11964 ]] Pass through the transform of the stack to make sure the measurment is correct for scaled text.
1075-
uint2 twidth;
1071+
coord_t twidth;
10761072
MCRange t_range;
10771073
t_range = MCRangeMake(sptr, l);
1078-
twidth = MCFontMeasureTextSubstring(m_font, parent->GetInternalStringRef(), t_range, parent -> getparent() -> getstack() -> getdevicetransform());
1074+
twidth = MCFontMeasureTextSubstringFloat(m_font, parent->GetInternalStringRef(), t_range, parent -> getparent() -> getstack() -> getdevicetransform());
10791075
twidth += gettabwidth(cx + twidth, eptr);
10801076
10811077
dc -> drawtext_substring(x, y, parent->GetInternalStringRef(), t_range, m_font, image == True, kMCDrawTextBreak, is_rtl() ? kMCDrawTextDirectionRTL : kMCDrawTextDirectionLTR);
@@ -1110,7 +1106,7 @@ void MCBlock::drawstring(MCDC *dc, int2 x, int2 p_cell_right, int2 y, findex_t s
11101106
}
11111107
}
11121108

1113-
void MCBlock::draw(MCDC *dc, int2 x, int2 cx, int2 y, findex_t si, findex_t ei, MCStringRef p_string, uint2 pstyle, uint32_t p_border_flags)
1109+
void MCBlock::draw(MCDC *dc, coord_t x, coord_t cx, int2 y, findex_t si, findex_t ei, MCStringRef p_string, uint2 pstyle, uint32_t p_border_flags)
11141110
{
11151111
if (flags & F_HAS_SHIFT)
11161112
y += atts->shift;
@@ -1230,7 +1226,7 @@ void MCBlock::draw(MCDC *dc, int2 x, int2 cx, int2 y, findex_t si, findex_t ei,
12301226
// If there is some unselected text at the end of the block, then render it.
12311227
if (ei < m_index + m_size)
12321228
{
1233-
int32_t t_end_dx;
1229+
coord_t t_end_dx;
12341230
t_end_dx = getsubwidth(dc, cx, m_index, ei - m_index);
12351231

12361232
MCRectangle t_unsel_clip;
@@ -1301,7 +1297,7 @@ void MCBlock::draw(MCDC *dc, int2 x, int2 cx, int2 y, findex_t si, findex_t ei,
13011297
t_old_clip = dc -> getclip();
13021298

13031299
// Compute the width of the block.
1304-
int32_t t_width;
1300+
coord_t t_width;
13051301
t_width = getwidth(dc, cx);
13061302

13071303
// Start off with the clip being that which it was previously.
@@ -1689,7 +1685,7 @@ void MCBlock::setbackcolor(const MCColor *newcolor)
16891685
}
16901686
}
16911687

1692-
uint2 MCBlock::GetCursorX(findex_t fi)
1688+
coord_t MCBlock::GetCursorX(findex_t fi)
16931689
{
16941690
findex_t j = fi - m_index;
16951691
if (j > m_size)
@@ -1703,7 +1699,7 @@ uint2 MCBlock::GetCursorX(findex_t fi)
17031699
return origin + getsubwidth(NULL, tabpos, m_index, j);
17041700
}
17051701

1706-
findex_t MCBlock::GetCursorIndex(int2 x, Boolean chunk, Boolean last)
1702+
findex_t MCBlock::GetCursorIndex(coord_t x, Boolean chunk, Boolean last)
17071703
{
17081704
// The x coordinate is relative to the line, not ourselves
17091705
x -= getorigin();
@@ -1719,16 +1715,16 @@ findex_t MCBlock::GetCursorIndex(int2 x, Boolean chunk, Boolean last)
17191715
}
17201716

17211717
findex_t i = m_index;
1722-
int2 cwidth;
1718+
coord_t cwidth;
17231719
findex_t tlen = 0;
1724-
uint2 twidth = 0;
1725-
uint2 toldwidth = 0;
1720+
coord_t twidth = 0;
1721+
coord_t toldwidth = 0;
17261722

17271723
// MW-2012-02-01: [[ Bug 9982 ]] iOS uses sub-pixel positioning, so make sure we measure
17281724
// complete runs.
17291725
// MW-2013-11-07: [[ Bug 11393 ]] We only want to measure complete runs now regardless of
17301726
// platform.
1731-
int32_t t_last_width;
1727+
coord_t t_last_width;
17321728
t_last_width = is_rtl() ? width : 0;
17331729

17341730
MCRange t_char_range;
@@ -1741,7 +1737,7 @@ findex_t MCBlock::GetCursorIndex(int2 x, Boolean chunk, Boolean last)
17411737
// SN-2014-03-26 [[ CombiningChars ]] We need to find the size of a char, starting from a given codepoint
17421738
t_new_i = parent -> NextChar(i);
17431739

1744-
int32_t t_new_width;
1740+
coord_t t_new_width;
17451741
t_new_width = GetCursorX(t_new_i) - origin;
17461742

17471743
int32_t t_pos;
@@ -1763,7 +1759,7 @@ findex_t MCBlock::GetCursorIndex(int2 x, Boolean chunk, Boolean last)
17631759
return i;
17641760
}
17651761

1766-
uint2 MCBlock::getsubwidth(MCDC *dc, int2 x /* IGNORED */, findex_t i, findex_t l)
1762+
coord_t MCBlock::getsubwidth(MCDC *dc, coord_t x /* IGNORED */, findex_t i, findex_t l)
17671763
{
17681764
if (l == 0)
17691765
return 0;
@@ -1783,7 +1779,7 @@ uint2 MCBlock::getsubwidth(MCDC *dc, int2 x /* IGNORED */, findex_t i, findex_t
17831779
// MW-2013-08-08: [[ Bug 10654 ]] Make sure we use a signed integer here, otherwise
17841780
// we get incorrect clamping when converted to unsigned.
17851781
// FG-2014-04-30: [[ TabAlignments ]] Blocks no longer contain tabs
1786-
int4 twidth = 0;
1782+
coord_t twidth = 0;
17871783
/*if (flags & F_HAS_TAB)
17881784
{
17891785
uindex_t eptr;
@@ -1796,7 +1792,7 @@ uint2 MCBlock::getsubwidth(MCDC *dc, int2 x /* IGNORED */, findex_t i, findex_t
17961792
MCRange t_range;
17971793
t_range = MCRangeMake(sptr, eptr - sptr);
17981794
// MM-2014-04-16: [[ Bug 11964 ]] Pass through the transform of the stack to make sure the measurment is correct for scaled text.
1799-
twidth += MCFontMeasureTextSubstring(m_font, parent->GetInternalStringRef(), t_range, parent -> getparent() -> getstack() -> getdevicetransform());
1795+
twidth += MCFontMeasureTextSubstringFloat(m_font, parent->GetInternalStringRef(), t_range, parent -> getparent() -> getstack() -> getdevicetransform());
18001796
18011797
twidth += gettabwidth(x + twidth, eptr);
18021798
@@ -1811,11 +1807,11 @@ uint2 MCBlock::getsubwidth(MCDC *dc, int2 x /* IGNORED */, findex_t i, findex_t
18111807
MCRange t_range;
18121808
t_range = MCRangeMake(sptr, l);
18131809
// MM-2014-04-16: [[ Bug 11964 ]] Pass through the transform of the stack to make sure the measurment is correct for scaled text.
1814-
return MCU_min(65535, twidth + MCFontMeasureTextSubstring(m_font, parent->GetInternalStringRef(), t_range, parent -> getparent() -> getstack() -> getdevicetransform()));
1810+
return twidth + MCFontMeasureTextSubstringFloat(m_font, parent->GetInternalStringRef(), t_range, parent -> getparent() -> getstack() -> getdevicetransform());
18151811
}
18161812
}
18171813

1818-
uint2 MCBlock::getwidth(MCDC *dc, int2 x)
1814+
coord_t MCBlock::getwidth(MCDC *dc, coord_t x)
18191815
{
18201816
if (flags & F_HAS_IMAGE && atts->image != NULL)
18211817
return atts->image->getrect().width;

engine/src/context.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,8 @@ class MCContext
170170
virtual void drawline(int2 x1, int2 y1, int2 x2, int2 y2) = 0;
171171
virtual void drawlines(MCPoint *points, uint2 npoints, bool p_closed = false) = 0;
172172
virtual void drawsegments(MCLineSegment *segments, uint2 nsegs) = 0;
173-
virtual void drawtext(int2 x, int2 y, MCStringRef p_string, MCFontRef p_font, Boolean image, MCDrawTextBreaking = kMCDrawTextBreak, MCDrawTextDirection = kMCDrawTextDirectionLTR) = 0;
174-
virtual void drawtext_substring(int2 x, int2 y, MCStringRef p_string, MCRange p_range, MCFontRef p_font, Boolean image, MCDrawTextBreaking = kMCDrawTextBreak, MCDrawTextDirection = kMCDrawTextDirectionLTR) = 0;
173+
virtual void drawtext(coord_t x, int2 y, MCStringRef p_string, MCFontRef p_font, Boolean image, MCDrawTextBreaking = kMCDrawTextBreak, MCDrawTextDirection = kMCDrawTextDirectionLTR) = 0;
174+
virtual void drawtext_substring(coord_t x, int2 y, MCStringRef p_string, MCRange p_range, MCFontRef p_font, Boolean image, MCDrawTextBreaking = kMCDrawTextBreak, MCDrawTextDirection = kMCDrawTextDirectionLTR) = 0;
175175
virtual void drawrect(const MCRectangle& rect, bool inside = false) = 0;
176176
virtual void fillrect(const MCRectangle& rect, bool inside = false) = 0;
177177
virtual void fillrects(MCRectangle *rects, uint2 nrects) = 0;

engine/src/exec-interface-field-chunk.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1561,7 +1561,7 @@ void MCField::GetFormattedTopOfCharChunk(MCExecContext& ctxt, uint32_t p_part_id
15611561
{
15621562
if (opened)
15631563
{
1564-
int2 x, y;
1564+
coord_t x, y;
15651565
MCParagraph *pgptr = resolveparagraphs(p_part_id);
15661566
MCParagraph *sptr = indextoparagraph(pgptr, si, ei, nil);
15671567
sptr -> indextoloc(si, fixedheight, x, y);
@@ -1578,14 +1578,14 @@ void MCField::GetFormattedLeftOfCharChunk(MCExecContext& ctxt, uint32_t p_part_i
15781578
{
15791579
MCParagraph *pgptr = resolveparagraphs(p_part_id);
15801580
MCParagraph *sptr = indextoparagraph(pgptr, si, ei, nil);
1581-
int2 minx, maxx;
1581+
coord_t minx, maxx;
15821582
findex_t t_si, t_ei; // needed to call MCParagraph::getextents
15831583

15841584
// MW-2008-07-08: [[ Bug 6331 ]] the formattedWidth can return gibberish for empty lines.
15851585
// This is because minx/maxx are uninitialized and it seems that they have to be for
15861586
// calls to getxextents() to make sense.
1587-
minx = MAXINT2;
1588-
maxx = MININT2;
1587+
minx = INFINITY;
1588+
maxx = -INFINITY;
15891589

15901590
do
15911591
{
@@ -1611,13 +1611,13 @@ void MCField::GetFormattedWidthOfCharChunk(MCExecContext& ctxt, uint32_t p_part_
16111611
{
16121612
MCParagraph *pgptr = resolveparagraphs(p_part_id);
16131613
MCParagraph *sptr = indextoparagraph(pgptr, si, ei, nil);
1614-
int2 minx, maxx;
1614+
coord_t minx, maxx;
16151615

16161616
// MW-2008-07-08: [[ Bug 6331 ]] the formattedWidth can return gibberish for empty lines.
16171617
// This is because minx/maxx are uninitialized and it seems that they have to be for
16181618
// calls to getxextents() to make sense.
1619-
minx = MAXINT2;
1620-
maxx = MININT2;
1619+
minx = INFINITY;
1620+
maxx = -INFINITY;
16211621

16221622
do
16231623
{
@@ -1642,7 +1642,7 @@ void MCField::GetFormattedHeightOfCharChunk(MCExecContext& ctxt, uint32_t p_part
16421642
// MW-2005-07-16: [[Bug 2938]] We must check to see if the field is open, if not we cannot do this.
16431643
if (opened)
16441644
{
1645-
int2 x, y;
1645+
coord_t x, y;
16461646
MCParagraph *pgptr = resolveparagraphs(p_part_id);
16471647
MCParagraph *sptr = indextoparagraph(resolveparagraphs(p_part_id), si, ei, nil);
16481648
sptr->indextoloc(si, fixedheight, x, y);
@@ -1668,16 +1668,16 @@ void MCField::GetFormattedRectOfCharChunk(MCExecContext& ctxt, uint32_t p_part_i
16681668
// MW-2005-07-16: [[Bug 2938]] We must check to see if the field is open, if not we cannot do this.
16691669
if (opened)
16701670
{
1671-
int2 x, y;
1671+
coord_t x, y;
16721672
MCParagraph *pgptr = resolveparagraphs(p_part_id);
16731673
MCParagraph *sptr = indextoparagraph(resolveparagraphs(p_part_id), si, ei, nil);
16741674
sptr->indextoloc(si, fixedheight, x, y);
16751675
// MW-2012-01-25: [[ FieldMetrics ]] Compute the yoffset in card-coords.
1676-
int4 yoffset = getcontenty() + paragraphtoy(sptr);
1677-
int2 minx, maxx;
1678-
int4 maxy = y;
1679-
minx = INT16_MAX;
1680-
maxx = INT16_MIN;
1676+
coord_t yoffset = getcontenty() + paragraphtoy(sptr);
1677+
coord_t minx, maxx;
1678+
coord_t maxy = y;
1679+
minx = INFINITY;
1680+
maxx = -INFINITY;
16811681
do
16821682
{
16831683
// MW-2012-01-25: [[ FieldMetrics ]] Increment the y-extent by the height of the

0 commit comments

Comments
 (0)