Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(630)

Side by Side Diff: Source/core/layout/svg/LayoutSVGInlineText.cpp

Issue 1072403007: Fixup a bug about SVG text selection. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Draft 19 Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « LayoutTests/svg/text/select-svg-text-with-collapsed-whitespace-expected.txt ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz> 2 * Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz>
3 * Copyright (C) 2006 Apple Computer Inc. 3 * Copyright (C) 2006 Apple Computer Inc.
4 * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> 4 * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
5 * Copyright (C) 2008 Rob Buis <buis@kde.org> 5 * Copyright (C) 2008 Rob Buis <buis@kde.org>
6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 6 * Copyright (C) Research In Motion Limited 2010. 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 // copy of the original character data content. First, it will remove all ne wline 52 // copy of the original character data content. First, it will remove all ne wline
53 // characters. Then it will convert all tab characters into space characters . 53 // characters. Then it will convert all tab characters into space characters .
54 // Then, it will strip off all leading and trailing space characters. 54 // Then, it will strip off all leading and trailing space characters.
55 // Then, all contiguous space characters will be consolidated. 55 // Then, all contiguous space characters will be consolidated.
56 RefPtr<StringImpl> newString = string->replace('\n', StringImpl::empty()); 56 RefPtr<StringImpl> newString = string->replace('\n', StringImpl::empty());
57 newString = newString->replace('\r', StringImpl::empty()); 57 newString = newString->replace('\r', StringImpl::empty());
58 newString = newString->replace('\t', ' '); 58 newString = newString->replace('\t', ' ');
59 return newString.release(); 59 return newString.release();
60 } 60 }
61 61
62 static float squaredDistanceToClosestPoint(const FloatRect& rect, const FloatPoi nt& point)
63 {
64 FloatPoint closestPoint;
65 closestPoint.setX(std::max(std::min(point.x(), rect.maxX()), rect.x()));
66 closestPoint.setY(std::max(std::min(point.y(), rect.maxY()), rect.y()));
67 return (point - closestPoint).diagonalLengthSquared();
68 }
69
62 LayoutSVGInlineText::LayoutSVGInlineText(Node* n, PassRefPtr<StringImpl> string) 70 LayoutSVGInlineText::LayoutSVGInlineText(Node* n, PassRefPtr<StringImpl> string)
63 : LayoutText(n, applySVGWhitespaceRules(string, false)) 71 : LayoutText(n, applySVGWhitespaceRules(string, false))
64 , m_scalingFactor(1) 72 , m_scalingFactor(1)
65 , m_layoutAttributes(this) 73 , m_layoutAttributes(this)
66 { 74 {
67 } 75 }
68 76
69 void LayoutSVGInlineText::setTextInternal(PassRefPtr<StringImpl> text) 77 void LayoutSVGInlineText::setTextInternal(PassRefPtr<StringImpl> text)
70 { 78 {
71 LayoutText::setTextInternal(text); 79 LayoutText::setTextInternal(text);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 return false; 156 return false;
149 157
150 return it->value.x != SVGTextLayoutAttributes::emptyValue() || it->value.y ! = SVGTextLayoutAttributes::emptyValue(); 158 return it->value.x != SVGTextLayoutAttributes::emptyValue() || it->value.y ! = SVGTextLayoutAttributes::emptyValue();
151 } 159 }
152 160
153 PositionWithAffinity LayoutSVGInlineText::positionForPoint(const LayoutPoint& po int) 161 PositionWithAffinity LayoutSVGInlineText::positionForPoint(const LayoutPoint& po int)
154 { 162 {
155 if (!firstTextBox() || !textLength()) 163 if (!firstTextBox() || !textLength())
156 return createPositionWithAffinity(0, DOWNSTREAM); 164 return createPositionWithAffinity(0, DOWNSTREAM);
157 165
158 float baseline = m_scaledFont.fontMetrics().floatAscent(); 166 ASSERT(m_scalingFactor);
167 float baseline = m_scaledFont.fontMetrics().floatAscent() / m_scalingFactor;
159 168
160 LayoutBlock* containingBlock = this->containingBlock(); 169 LayoutBlock* containingBlock = this->containingBlock();
161 ASSERT(containingBlock); 170 ASSERT(containingBlock);
162 171
163 // Map local point to absolute point, as the character origins stored in the text fragments use absolute coordinates. 172 // Map local point to absolute point, as the character origins stored in the text fragments use absolute coordinates.
164 FloatPoint absolutePoint(point); 173 FloatPoint absolutePoint(point);
165 absolutePoint.moveBy(containingBlock->location()); 174 absolutePoint.moveBy(containingBlock->location());
166 175
167 float closestDistance = std::numeric_limits<float>::max(); 176 float closestDistance = std::numeric_limits<float>::max();
168 float closestDistancePosition = 0; 177 float closestDistancePosition = 0;
169 const SVGTextFragment* closestDistanceFragment = 0; 178 const SVGTextFragment* closestDistanceFragment = 0;
170 SVGInlineTextBox* closestDistanceBox = 0; 179 SVGInlineTextBox* closestDistanceBox = 0;
171 180
172 AffineTransform fragmentTransform; 181 AffineTransform fragmentTransform;
173 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 182 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
174 if (!box->isSVGInlineTextBox()) 183 if (!box->isSVGInlineTextBox())
175 continue; 184 continue;
176 185
177 SVGInlineTextBox* textBox = toSVGInlineTextBox(box); 186 SVGInlineTextBox* textBox = toSVGInlineTextBox(box);
178 Vector<SVGTextFragment>& fragments = textBox->textFragments(); 187 Vector<SVGTextFragment>& fragments = textBox->textFragments();
179 188
180 unsigned textFragmentsSize = fragments.size(); 189 unsigned textFragmentsSize = fragments.size();
181 for (unsigned i = 0; i < textFragmentsSize; ++i) { 190 for (unsigned i = 0; i < textFragmentsSize; ++i) {
182 const SVGTextFragment& fragment = fragments.at(i); 191 const SVGTextFragment& fragment = fragments.at(i);
183 FloatRect fragmentRect(fragment.x, fragment.y - baseline, fragment.w idth, fragment.height); 192 FloatRect fragmentRect(fragment.x, fragment.y - baseline, fragment.w idth, fragment.height);
184 fragment.buildFragmentTransform(fragmentTransform); 193 fragment.buildFragmentTransform(fragmentTransform);
185 fragmentRect = fragmentTransform.mapRect(fragmentRect); 194 if (!fragmentTransform.isIdentity())
195 fragmentRect = fragmentTransform.mapRect(fragmentRect);
186 196
187 float distance = powf(fragmentRect.x() - absolutePoint.x(), 2) + 197 float distance = 0;
188 powf(fragmentRect.y() + fragmentRect.height() / 2 - absolutePoin t.y(), 2); 198 if (!fragmentRect.contains(absolutePoint))
199 distance = squaredDistanceToClosestPoint(fragmentRect, absoluteP oint);
189 200
190 if (distance < closestDistance) { 201 if (distance <= closestDistance) {
191 closestDistance = distance; 202 closestDistance = distance;
192 closestDistanceBox = textBox; 203 closestDistanceBox = textBox;
193 closestDistanceFragment = &fragment; 204 closestDistanceFragment = &fragment;
194 closestDistancePosition = fragmentRect.x(); 205 closestDistancePosition = fragmentRect.x();
195 } 206 }
196 } 207 }
197 } 208 }
198 209
199 if (!closestDistanceFragment) 210 if (!closestDistanceFragment)
200 return createPositionWithAffinity(0, DOWNSTREAM); 211 return createPositionWithAffinity(0, DOWNSTREAM);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 255
245 PassRefPtr<StringImpl> LayoutSVGInlineText::originalText() const 256 PassRefPtr<StringImpl> LayoutSVGInlineText::originalText() const
246 { 257 {
247 RefPtr<StringImpl> result = LayoutText::originalText(); 258 RefPtr<StringImpl> result = LayoutText::originalText();
248 if (!result) 259 if (!result)
249 return nullptr; 260 return nullptr;
250 return applySVGWhitespaceRules(result, style() && style()->whiteSpace() == P RE); 261 return applySVGWhitespaceRules(result, style() && style()->whiteSpace() == P RE);
251 } 262 }
252 263
253 } 264 }
OLDNEW
« no previous file with comments | « LayoutTests/svg/text/select-svg-text-with-collapsed-whitespace-expected.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698