OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 template<typename CharType> | 44 template<typename CharType> |
45 inline bool isComma(CharType character) | 45 inline bool isComma(CharType character) |
46 { | 46 { |
47 return character == ','; | 47 return character == ','; |
48 } | 48 } |
49 | 49 |
50 template<typename CharType> | 50 template<typename CharType> |
51 static bool parseDescriptors(const CharType* descriptorsStart, const CharType* d
escriptorsEnd, float& imgScaleFactor) | 51 static bool parseDescriptors(const CharType* descriptorsStart, const CharType* d
escriptorsEnd, float& imgScaleFactor) |
52 { | 52 { |
53 const CharType* position = descriptorsStart; | 53 const CharType* position = descriptorsStart; |
54 bool isValid = true; | 54 bool isValid = false; |
55 bool isScaleFactorFound = false; | 55 bool isFoundScaleFactor = false; |
| 56 bool isEmptyDescriptor = !(descriptorsEnd > descriptorsStart); |
56 while (position < descriptorsEnd) { | 57 while (position < descriptorsEnd) { |
57 // 13.1. Let descriptor list be the result of splitting unparsed descrip
tors on spaces. | 58 // 13.1. Let descriptor list be the result of splitting unparsed descrip
tors on spaces. |
58 skipWhile<CharType, isHTMLSpace<CharType> >(position, descriptorsEnd); | 59 skipWhile<CharType, isHTMLSpace<CharType> >(position, descriptorsEnd); |
59 const CharType* currentDescriptorStart = position; | 60 const CharType* currentDescriptorStart = position; |
60 skipWhile<CharType, isNotHTMLSpace<CharType> >(position, descriptorsEnd)
; | 61 skipWhile<CharType, isNotHTMLSpace<CharType> >(position, descriptorsEnd)
; |
61 const CharType* currentDescriptorEnd = position; | 62 const CharType* currentDescriptorEnd = position; |
62 | 63 |
63 ++position; | 64 ++position; |
64 ASSERT(currentDescriptorEnd > currentDescriptorStart); | 65 ASSERT(currentDescriptorEnd > currentDescriptorStart); |
65 --currentDescriptorEnd; | 66 --currentDescriptorEnd; |
66 unsigned descriptorLength = currentDescriptorEnd - currentDescriptorStar
t; | 67 unsigned descriptorLength = currentDescriptorEnd - currentDescriptorStar
t; |
67 if (*currentDescriptorEnd == 'x') { | 68 if (*currentDescriptorEnd == 'x') { |
68 if (isScaleFactorFound) | 69 if (isFoundScaleFactor) |
69 return false; | 70 return false; |
70 imgScaleFactor = charactersToFloat(currentDescriptorStart, descripto
rLength, &isValid); | 71 imgScaleFactor = charactersToFloat(currentDescriptorStart, descripto
rLength, &isValid); |
71 isScaleFactorFound = true; | 72 isFoundScaleFactor = true; |
72 } else { | 73 } else { |
73 continue; | 74 continue; |
74 } | 75 } |
75 } | 76 } |
76 return isValid; | 77 return isEmptyDescriptor || isValid; |
77 } | 78 } |
78 | 79 |
79 // http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content-
1.html#processing-the-image-candidates | 80 // http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content-
1.html#processing-the-image-candidates |
80 template<typename CharType> | 81 template<typename CharType> |
81 static void parseImageCandidatesFromSrcsetAttribute(const String& attribute, con
st CharType* attributeStart, unsigned length, Vector<ImageCandidate>& imageCandi
dates) | 82 static void parseImageCandidatesFromSrcsetAttribute(const String& attribute, con
st CharType* attributeStart, unsigned length, Vector<ImageCandidate>& imageCandi
dates) |
82 { | 83 { |
83 const CharType* position = attributeStart; | 84 const CharType* position = attributeStart; |
84 const CharType* attributeEnd = position + length; | 85 const CharType* attributeEnd = position + length; |
85 | 86 |
86 while (position < attributeEnd) { | 87 while (position < attributeEnd) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 } | 132 } |
132 | 133 |
133 static ImageCandidate pickBestImageCandidate(float deviceScaleFactor, Vector<Ima
geCandidate>& imageCandidates) | 134 static ImageCandidate pickBestImageCandidate(float deviceScaleFactor, Vector<Ima
geCandidate>& imageCandidates) |
134 { | 135 { |
135 if (imageCandidates.isEmpty()) | 136 if (imageCandidates.isEmpty()) |
136 return ImageCandidate(); | 137 return ImageCandidate(); |
137 | 138 |
138 std::stable_sort(imageCandidates.begin(), imageCandidates.end(), compareBySc
aleFactor); | 139 std::stable_sort(imageCandidates.begin(), imageCandidates.end(), compareBySc
aleFactor); |
139 | 140 |
140 unsigned i; | 141 unsigned i; |
141 for (i = 0; i < imageCandidates.size() - 1; ++i) { | 142 for (i = 0; i < imageCandidates.size() - 1; ++i) |
142 if (imageCandidates[i].scaleFactor() >= deviceScaleFactor) | 143 if (imageCandidates[i].scaleFactor() >= deviceScaleFactor) |
143 break; | 144 break; |
144 } | 145 |
145 return imageCandidates[i]; | 146 float winningScaleFactor = imageCandidates[i].scaleFactor(); |
| 147 unsigned winner = i; |
| 148 // 16. If an entry b in candidates has the same associated ... pixel density
as an earlier entry a in candidates, |
| 149 // then remove entry b |
| 150 while ((i > 0) && (imageCandidates[--i].scaleFactor() == winningScaleFactor)
) |
| 151 winner = i; |
| 152 |
| 153 return imageCandidates[winner]; |
146 } | 154 } |
147 | 155 |
148 ImageCandidate bestFitSourceForSrcsetAttribute(float deviceScaleFactor, const St
ring& srcsetAttribute) | 156 ImageCandidate bestFitSourceForSrcsetAttribute(float deviceScaleFactor, const St
ring& srcsetAttribute) |
149 { | 157 { |
150 Vector<ImageCandidate> imageCandidates; | 158 Vector<ImageCandidate> imageCandidates; |
151 | 159 |
152 parseImageCandidatesFromSrcsetAttribute(srcsetAttribute, imageCandidates); | 160 parseImageCandidatesFromSrcsetAttribute(srcsetAttribute, imageCandidates); |
153 | 161 |
154 return pickBestImageCandidate(deviceScaleFactor, imageCandidates); | 162 return pickBestImageCandidate(deviceScaleFactor, imageCandidates); |
155 } | 163 } |
(...skipping 24 matching lines...) Expand all Loading... |
180 Vector<ImageCandidate> imageCandidates; | 188 Vector<ImageCandidate> imageCandidates; |
181 imageCandidates.append(srcsetImageCandidate); | 189 imageCandidates.append(srcsetImageCandidate); |
182 | 190 |
183 if (!srcAttribute.isEmpty()) | 191 if (!srcAttribute.isEmpty()) |
184 imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.leng
th(), 1.0)); | 192 imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.leng
th(), 1.0)); |
185 | 193 |
186 return pickBestImageCandidate(deviceScaleFactor, imageCandidates).toString()
; | 194 return pickBestImageCandidate(deviceScaleFactor, imageCandidates).toString()
; |
187 } | 195 } |
188 | 196 |
189 } | 197 } |
OLD | NEW |