| OLD | NEW |
| 1 /* | 1 /* |
| 2 * (C) 1999 Lars Knoll (knoll@kde.org) | 2 * (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 2000 Dirk Mueller (mueller@kde.org) | 3 * (C) 2000 Dirk Mueller (mueller@kde.org) |
| 4 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. | 4 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. |
| 5 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) | 5 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) |
| 6 * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com) | 6 * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com) |
| 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 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 } else { | 245 } else { |
| 246 r.setWidth(box->width()); | 246 r.setWidth(box->width()); |
| 247 r.setX(box->x()); | 247 r.setX(box->x()); |
| 248 } | 248 } |
| 249 } | 249 } |
| 250 return FloatRect(r); | 250 return FloatRect(r); |
| 251 } | 251 } |
| 252 return FloatRect(); | 252 return FloatRect(); |
| 253 } | 253 } |
| 254 | 254 |
| 255 void RenderText::absoluteRectsForRange(Vector<IntRect>& rects, unsigned start, u
nsigned end, bool useSelectionHeight, bool* wasFixed) | 255 void RenderText::absoluteRectsForRange(Vector<IntRect>& rects, unsigned start, u
nsigned end, bool useSelectionHeight) |
| 256 { | 256 { |
| 257 // Work around signed/unsigned issues. This function takes unsigneds, and is
often passed UINT_MAX | 257 // Work around signed/unsigned issues. This function takes unsigneds, and is
often passed UINT_MAX |
| 258 // to mean "all the way to the end". InlineTextBox coordinates are unsigneds
, so changing this | 258 // to mean "all the way to the end". InlineTextBox coordinates are unsigneds
, so changing this |
| 259 // function to take ints causes various internal mismatches. But selectionRe
ct takes ints, and | 259 // function to take ints causes various internal mismatches. But selectionRe
ct takes ints, and |
| 260 // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect
to take unsigneds, but | 260 // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect
to take unsigneds, but |
| 261 // that would cause many ripple effects, so for now we'll just clamp our uns
igned parameters to INT_MAX. | 261 // that would cause many ripple effects, so for now we'll just clamp our uns
igned parameters to INT_MAX. |
| 262 ASSERT(end == UINT_MAX || end <= INT_MAX); | 262 ASSERT(end == UINT_MAX || end <= INT_MAX); |
| 263 ASSERT(start <= INT_MAX); | 263 ASSERT(start <= INT_MAX); |
| 264 start = std::min(start, static_cast<unsigned>(INT_MAX)); | 264 start = std::min(start, static_cast<unsigned>(INT_MAX)); |
| 265 end = std::min(end, static_cast<unsigned>(INT_MAX)); | 265 end = std::min(end, static_cast<unsigned>(INT_MAX)); |
| 266 | 266 |
| 267 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { | 267 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { |
| 268 // Note: box->end() returns the index of the last character, not the ind
ex past it | 268 // Note: box->end() returns the index of the last character, not the ind
ex past it |
| 269 if (start <= box->start() && box->end() < end) { | 269 if (start <= box->start() && box->end() < end) { |
| 270 FloatRect r = box->calculateBoundaries(); | 270 FloatRect r = box->calculateBoundaries(); |
| 271 if (useSelectionHeight) { | 271 if (useSelectionHeight) { |
| 272 LayoutRect selectionRect = box->localSelectionRect(start, end); | 272 LayoutRect selectionRect = box->localSelectionRect(start, end); |
| 273 if (box->isHorizontal()) { | 273 if (box->isHorizontal()) { |
| 274 r.setHeight(selectionRect.height().toFloat()); | 274 r.setHeight(selectionRect.height().toFloat()); |
| 275 r.setY(selectionRect.y().toFloat()); | 275 r.setY(selectionRect.y().toFloat()); |
| 276 } else { | 276 } else { |
| 277 r.setWidth(selectionRect.width().toFloat()); | 277 r.setWidth(selectionRect.width().toFloat()); |
| 278 r.setX(selectionRect.x().toFloat()); | 278 r.setX(selectionRect.x().toFloat()); |
| 279 } | 279 } |
| 280 } | 280 } |
| 281 rects.append(localToAbsoluteQuad(r, 0, wasFixed).enclosingBoundingBo
x()); | 281 rects.append(localToAbsoluteQuad(r, 0).enclosingBoundingBox()); |
| 282 } else { | 282 } else { |
| 283 // FIXME: This code is wrong. It's converting local to absolute twic
e. http://webkit.org/b/65722 | 283 // FIXME: This code is wrong. It's converting local to absolute twic
e. http://webkit.org/b/65722 |
| 284 FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHe
ight); | 284 FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHe
ight); |
| 285 if (!rect.isZero()) | 285 if (!rect.isZero()) |
| 286 rects.append(localToAbsoluteQuad(rect, 0, wasFixed).enclosingBou
ndingBox()); | 286 rects.append(localToAbsoluteQuad(rect, 0).enclosingBoundingBox()
); |
| 287 } | 287 } |
| 288 } | 288 } |
| 289 } | 289 } |
| 290 | 290 |
| 291 static IntRect ellipsisRectForBox(InlineTextBox* box, unsigned startPos, unsigne
d endPos) | 291 static IntRect ellipsisRectForBox(InlineTextBox* box, unsigned startPos, unsigne
d endPos) |
| 292 { | 292 { |
| 293 if (!box) | 293 if (!box) |
| 294 return IntRect(); | 294 return IntRect(); |
| 295 | 295 |
| 296 unsigned short truncation = box->truncation(); | 296 unsigned short truncation = box->truncation(); |
| 297 if (truncation == cNoTruncation) | 297 if (truncation == cNoTruncation) |
| 298 return IntRect(); | 298 return IntRect(); |
| 299 | 299 |
| 300 IntRect rect; | 300 IntRect rect; |
| 301 if (EllipsisBox* ellipsis = box->root().ellipsisBox()) { | 301 if (EllipsisBox* ellipsis = box->root().ellipsisBox()) { |
| 302 int ellipsisStartPosition = std::max<int>(startPos - box->start(), 0); | 302 int ellipsisStartPosition = std::max<int>(startPos - box->start(), 0); |
| 303 int ellipsisEndPosition = std::min<int>(endPos - box->start(), box->len(
)); | 303 int ellipsisEndPosition = std::min<int>(endPos - box->start(), box->len(
)); |
| 304 | 304 |
| 305 // The ellipsis should be considered to be selected if the end of | 305 // The ellipsis should be considered to be selected if the end of |
| 306 // the selection is past the beginning of the truncation and the | 306 // the selection is past the beginning of the truncation and the |
| 307 // beginning of the selection is before or at the beginning of the trunc
ation. | 307 // beginning of the selection is before or at the beginning of the trunc
ation. |
| 308 if (ellipsisEndPosition >= truncation && ellipsisStartPosition <= trunca
tion) | 308 if (ellipsisEndPosition >= truncation && ellipsisStartPosition <= trunca
tion) |
| 309 return ellipsis->selectionRect(); | 309 return ellipsis->selectionRect(); |
| 310 } | 310 } |
| 311 | 311 |
| 312 return IntRect(); | 312 return IntRect(); |
| 313 } | 313 } |
| 314 | 314 |
| 315 void RenderText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed, Clippin
gOption option) const | 315 void RenderText::absoluteQuads(Vector<FloatQuad>& quads, ClippingOption option)
const |
| 316 { | 316 { |
| 317 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { | 317 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { |
| 318 FloatRect boundaries = box->calculateBoundaries(); | 318 FloatRect boundaries = box->calculateBoundaries(); |
| 319 | 319 |
| 320 // Shorten the width of this text box if it ends in an ellipsis. | 320 // Shorten the width of this text box if it ends in an ellipsis. |
| 321 // FIXME: ellipsisRectForBox should switch to return FloatRect soon with
the subpixellayout branch. | 321 // FIXME: ellipsisRectForBox should switch to return FloatRect soon with
the subpixellayout branch. |
| 322 IntRect ellipsisRect = (option == ClipToEllipsis) ? ellipsisRectForBox(b
ox, 0, textLength()) : IntRect(); | 322 IntRect ellipsisRect = (option == ClipToEllipsis) ? ellipsisRectForBox(b
ox, 0, textLength()) : IntRect(); |
| 323 if (!ellipsisRect.isEmpty()) { | 323 if (!ellipsisRect.isEmpty()) { |
| 324 if (style()->isHorizontalWritingMode()) | 324 if (style()->isHorizontalWritingMode()) |
| 325 boundaries.setWidth(ellipsisRect.maxX() - boundaries.x()); | 325 boundaries.setWidth(ellipsisRect.maxX() - boundaries.x()); |
| 326 else | 326 else |
| 327 boundaries.setHeight(ellipsisRect.maxY() - boundaries.y()); | 327 boundaries.setHeight(ellipsisRect.maxY() - boundaries.y()); |
| 328 } | 328 } |
| 329 quads.append(localToAbsoluteQuad(boundaries, 0, wasFixed)); | 329 quads.append(localToAbsoluteQuad(boundaries, 0)); |
| 330 } | 330 } |
| 331 } | 331 } |
| 332 | 332 |
| 333 void RenderText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const | 333 void RenderText::absoluteQuads(Vector<FloatQuad>& quads) const |
| 334 { | 334 { |
| 335 absoluteQuads(quads, wasFixed, NoClipping); | 335 absoluteQuads(quads, NoClipping); |
| 336 } | 336 } |
| 337 | 337 |
| 338 void RenderText::absoluteQuadsForRange(Vector<FloatQuad>& quads, unsigned start,
unsigned end, bool useSelectionHeight, bool* wasFixed) | 338 void RenderText::absoluteQuadsForRange(Vector<FloatQuad>& quads, unsigned start,
unsigned end, bool useSelectionHeight) |
| 339 { | 339 { |
| 340 // Work around signed/unsigned issues. This function takes unsigneds, and is
often passed UINT_MAX | 340 // Work around signed/unsigned issues. This function takes unsigneds, and is
often passed UINT_MAX |
| 341 // to mean "all the way to the end". InlineTextBox coordinates are unsigneds
, so changing this | 341 // to mean "all the way to the end". InlineTextBox coordinates are unsigneds
, so changing this |
| 342 // function to take ints causes various internal mismatches. But selectionRe
ct takes ints, and | 342 // function to take ints causes various internal mismatches. But selectionRe
ct takes ints, and |
| 343 // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect
to take unsigneds, but | 343 // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect
to take unsigneds, but |
| 344 // that would cause many ripple effects, so for now we'll just clamp our uns
igned parameters to INT_MAX. | 344 // that would cause many ripple effects, so for now we'll just clamp our uns
igned parameters to INT_MAX. |
| 345 ASSERT(end == UINT_MAX || end <= INT_MAX); | 345 ASSERT(end == UINT_MAX || end <= INT_MAX); |
| 346 ASSERT(start <= INT_MAX); | 346 ASSERT(start <= INT_MAX); |
| 347 start = std::min(start, static_cast<unsigned>(INT_MAX)); | 347 start = std::min(start, static_cast<unsigned>(INT_MAX)); |
| 348 end = std::min(end, static_cast<unsigned>(INT_MAX)); | 348 end = std::min(end, static_cast<unsigned>(INT_MAX)); |
| 349 | 349 |
| 350 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { | 350 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { |
| 351 // Note: box->end() returns the index of the last character, not the ind
ex past it | 351 // Note: box->end() returns the index of the last character, not the ind
ex past it |
| 352 if (start <= box->start() && box->end() < end) { | 352 if (start <= box->start() && box->end() < end) { |
| 353 FloatRect r = box->calculateBoundaries(); | 353 FloatRect r = box->calculateBoundaries(); |
| 354 if (useSelectionHeight) { | 354 if (useSelectionHeight) { |
| 355 LayoutRect selectionRect = box->localSelectionRect(start, end); | 355 LayoutRect selectionRect = box->localSelectionRect(start, end); |
| 356 if (box->isHorizontal()) { | 356 if (box->isHorizontal()) { |
| 357 r.setHeight(selectionRect.height().toFloat()); | 357 r.setHeight(selectionRect.height().toFloat()); |
| 358 r.setY(selectionRect.y().toFloat()); | 358 r.setY(selectionRect.y().toFloat()); |
| 359 } else { | 359 } else { |
| 360 r.setWidth(selectionRect.width().toFloat()); | 360 r.setWidth(selectionRect.width().toFloat()); |
| 361 r.setX(selectionRect.x().toFloat()); | 361 r.setX(selectionRect.x().toFloat()); |
| 362 } | 362 } |
| 363 } | 363 } |
| 364 quads.append(localToAbsoluteQuad(r, 0, wasFixed)); | 364 quads.append(localToAbsoluteQuad(r, 0)); |
| 365 } else { | 365 } else { |
| 366 FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHe
ight); | 366 FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHe
ight); |
| 367 if (!rect.isZero()) | 367 if (!rect.isZero()) |
| 368 quads.append(localToAbsoluteQuad(rect, 0, wasFixed)); | 368 quads.append(localToAbsoluteQuad(rect, 0)); |
| 369 } | 369 } |
| 370 } | 370 } |
| 371 } | 371 } |
| 372 | 372 |
| 373 enum ShouldAffinityBeDownstream { AlwaysDownstream, AlwaysUpstream, UpstreamIfPo
sitionIsNotAtStart }; | 373 enum ShouldAffinityBeDownstream { AlwaysDownstream, AlwaysUpstream, UpstreamIfPo
sitionIsNotAtStart }; |
| 374 | 374 |
| 375 static bool lineDirectionPointFitsInBox(int pointLineDirection, InlineTextBox* b
ox, ShouldAffinityBeDownstream& shouldAffinityBeDownstream) | 375 static bool lineDirectionPointFitsInBox(int pointLineDirection, InlineTextBox* b
ox, ShouldAffinityBeDownstream& shouldAffinityBeDownstream) |
| 376 { | 376 { |
| 377 shouldAffinityBeDownstream = AlwaysDownstream; | 377 shouldAffinityBeDownstream = AlwaysDownstream; |
| 378 | 378 |
| (...skipping 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1680 ASSERT(child->prevTextBox() == prev); | 1680 ASSERT(child->prevTextBox() == prev); |
| 1681 prev = child; | 1681 prev = child; |
| 1682 } | 1682 } |
| 1683 ASSERT(prev == m_lastTextBox); | 1683 ASSERT(prev == m_lastTextBox); |
| 1684 #endif | 1684 #endif |
| 1685 } | 1685 } |
| 1686 | 1686 |
| 1687 #endif | 1687 #endif |
| 1688 | 1688 |
| 1689 } // namespace blink | 1689 } // namespace blink |
| OLD | NEW |