OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2000 Dirk Mueller (mueller@kde.org) | 4 * (C) 2000 Dirk Mueller (mueller@kde.org) |
5 * Copyright (C) 2003, 2006, 2010, 2011 Apple Inc. All rights reserved. | 5 * Copyright (C) 2003, 2006, 2010, 2011 Apple Inc. All rights reserved. |
6 * Copyright (c) 2007, 2008, 2010 Google Inc. All rights reserved. | 6 * Copyright (c) 2007, 2008, 2010 Google Inc. All rights reserved. |
7 * | 7 * |
8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 const float* advances = glyphBuffer.advances(start); | 319 const float* advances = glyphBuffer.advances(start); |
320 for (unsigned j = 0; j < count; j++) { | 320 for (unsigned j = 0; j < count; j++) { |
321 buffer.pos[j] = x; | 321 buffer.pos[j] = x; |
322 x += SkFloatToScalar(advances[j]); | 322 x += SkFloatToScalar(advances[j]); |
323 } | 323 } |
324 } | 324 } |
325 | 325 |
326 return adoptRef(builder.build()); | 326 return adoptRef(builder.build()); |
327 } | 327 } |
328 | 328 |
| 329 static inline FloatRect pixelSnappedSelectionRect(FloatRect rect) |
| 330 { |
| 331 // Using roundf() rather than ceilf() for the right edge as a compromise to |
| 332 // ensure correct caret positioning. |
| 333 float roundedX = roundf(rect.x()); |
| 334 return FloatRect(roundedX, rect.y(), roundf(rect.maxX() - roundedX), rect.he
ight()); |
| 335 } |
329 | 336 |
330 FloatRect Font::selectionRectForText(const TextRun& run, const FloatPoint& point
, int h, int from, int to, bool accountForGlyphBounds) const | 337 FloatRect Font::selectionRectForText(const TextRun& run, const FloatPoint& point
, int h, int from, int to, bool accountForGlyphBounds) const |
331 { | 338 { |
332 to = (to == -1 ? run.length() : to); | 339 to = (to == -1 ? run.length() : to); |
333 | 340 |
334 TextRunPaintInfo runInfo(run); | 341 TextRunPaintInfo runInfo(run); |
335 runInfo.from = from; | 342 runInfo.from = from; |
336 runInfo.to = to; | 343 runInfo.to = to; |
337 | 344 |
338 if (codePath(runInfo) != ComplexPath) | 345 if (codePath(runInfo) != ComplexPath) |
339 return selectionRectForSimpleText(run, point, h, from, to, accountForGly
phBounds); | 346 return pixelSnappedSelectionRect(selectionRectForSimpleText(run, point,
h, from, to, accountForGlyphBounds)); |
340 | 347 return pixelSnappedSelectionRect(selectionRectForComplexText(run, point, h,
from, to)); |
341 return selectionRectForComplexText(run, point, h, from, to); | |
342 } | 348 } |
343 | 349 |
344 int Font::offsetForPosition(const TextRun& run, float x, bool includePartialGlyp
hs) const | 350 int Font::offsetForPosition(const TextRun& run, float x, bool includePartialGlyp
hs) const |
345 { | 351 { |
346 if (codePath(TextRunPaintInfo(run)) != ComplexPath && !fontDescription().typ
esettingFeatures()) | 352 if (codePath(TextRunPaintInfo(run)) != ComplexPath && !fontDescription().typ
esettingFeatures()) |
347 return offsetForPositionForSimpleText(run, x, includePartialGlyphs); | 353 return offsetForPositionForSimpleText(run, x, includePartialGlyphs); |
348 | 354 |
349 return offsetForPositionForComplexText(run, x, includePartialGlyphs); | 355 return offsetForPositionForComplexText(run, x, includePartialGlyphs); |
350 } | 356 } |
351 | 357 |
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1039 if (glyphBounds) { | 1045 if (glyphBounds) { |
1040 glyphBounds->setTop(floorf(-bounds.minGlyphBoundingBoxY)); | 1046 glyphBounds->setTop(floorf(-bounds.minGlyphBoundingBoxY)); |
1041 glyphBounds->setBottom(ceilf(bounds.maxGlyphBoundingBoxY)); | 1047 glyphBounds->setBottom(ceilf(bounds.maxGlyphBoundingBoxY)); |
1042 glyphBounds->setLeft(floorf(bounds.firstGlyphOverflow)); | 1048 glyphBounds->setLeft(floorf(bounds.firstGlyphOverflow)); |
1043 glyphBounds->setRight(ceilf(bounds.lastGlyphOverflow)); | 1049 glyphBounds->setRight(ceilf(bounds.lastGlyphOverflow)); |
1044 } | 1050 } |
1045 | 1051 |
1046 return shaper.runWidthSoFar(); | 1052 return shaper.runWidthSoFar(); |
1047 } | 1053 } |
1048 | 1054 |
1049 FloatRect Font::pixelSnappedSelectionRect(float fromX, float toX, float y, float
height) | |
1050 { | |
1051 // Using roundf() rather than ceilf() for the right edge as a compromise to | |
1052 // ensure correct caret positioning. | |
1053 float roundedX = roundf(fromX); | |
1054 return FloatRect(roundedX, y, roundf(toX - roundedX), height); | |
1055 } | |
1056 | |
1057 FloatRect Font::selectionRectForSimpleText(const TextRun& run, const FloatPoint&
point, int h, int from, int to, bool accountForGlyphBounds) const | 1055 FloatRect Font::selectionRectForSimpleText(const TextRun& run, const FloatPoint&
point, int h, int from, int to, bool accountForGlyphBounds) const |
1058 { | 1056 { |
1059 SimpleShaper::GlyphBounds bounds; | 1057 SimpleShaper::GlyphBounds bounds; |
1060 SimpleShaper shaper(this, run, 0, accountForGlyphBounds ? &bounds : 0); | 1058 SimpleShaper shaper(this, run, 0, accountForGlyphBounds ? &bounds : 0); |
1061 shaper.advance(from); | 1059 shaper.advance(from); |
1062 float fromX = shaper.runWidthSoFar(); | 1060 float fromX = shaper.runWidthSoFar(); |
1063 shaper.advance(to); | 1061 shaper.advance(to); |
1064 float toX = shaper.runWidthSoFar(); | 1062 float toX = shaper.runWidthSoFar(); |
1065 | 1063 |
1066 if (run.rtl()) { | 1064 if (run.rtl()) { |
1067 shaper.advance(run.length()); | 1065 shaper.advance(run.length()); |
1068 float totalWidth = shaper.runWidthSoFar(); | 1066 float totalWidth = shaper.runWidthSoFar(); |
1069 float beforeWidth = fromX; | 1067 float beforeWidth = fromX; |
1070 float afterWidth = toX; | 1068 float afterWidth = toX; |
1071 fromX = totalWidth - afterWidth; | 1069 fromX = totalWidth - afterWidth; |
1072 toX = totalWidth - beforeWidth; | 1070 toX = totalWidth - beforeWidth; |
1073 } | 1071 } |
1074 | 1072 |
1075 return pixelSnappedSelectionRect(point.x() + fromX, point.x() + toX, | 1073 return FloatRect(point.x() + fromX, |
1076 accountForGlyphBounds ? bounds.minGlyphBoundingBoxY : point.y(), | 1074 accountForGlyphBounds ? bounds.minGlyphBoundingBoxY : point.y(), |
| 1075 toX - fromX, |
1077 accountForGlyphBounds ? bounds.maxGlyphBoundingBoxY - bounds.minGlyphBou
ndingBoxY : h); | 1076 accountForGlyphBounds ? bounds.maxGlyphBoundingBoxY - bounds.minGlyphBou
ndingBoxY : h); |
1078 } | 1077 } |
1079 | 1078 |
1080 int Font::offsetForPositionForSimpleText(const TextRun& run, float x, bool inclu
dePartialGlyphs) const | 1079 int Font::offsetForPositionForSimpleText(const TextRun& run, float x, bool inclu
dePartialGlyphs) const |
1081 { | 1080 { |
1082 float delta = x; | 1081 float delta = x; |
1083 | 1082 |
1084 SimpleShaper shaper(this, run); | 1083 SimpleShaper shaper(this, run); |
1085 unsigned offset; | 1084 unsigned offset; |
1086 if (run.rtl()) { | 1085 if (run.rtl()) { |
(...skipping 26 matching lines...) Expand all Loading... |
1113 if (delta <= 0) | 1112 if (delta <= 0) |
1114 break; | 1113 break; |
1115 } | 1114 } |
1116 } | 1115 } |
1117 } | 1116 } |
1118 | 1117 |
1119 return offset; | 1118 return offset; |
1120 } | 1119 } |
1121 | 1120 |
1122 } // namespace blink | 1121 } // namespace blink |
OLD | NEW |