| 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 if (*currentDescriptorEnd == 'x') { | 68 if (*currentDescriptorEnd == 'x') { |
| 69 if (result.foundDescriptor()) | 69 if (result.foundDescriptor()) |
| 70 return false; | 70 return false; |
| 71 result.scaleFactor = charactersToFloat(currentDescriptorStart, descr
iptorLength, &isValid); | 71 result.scaleFactor = charactersToFloat(currentDescriptorStart, descr
iptorLength, &isValid); |
| 72 if (!isValid || result.scaleFactor < 0) | 72 if (!isValid || result.scaleFactor < 0) |
| 73 return false; | 73 return false; |
| 74 } else if (RuntimeEnabledFeatures::pictureSizesEnabled() && *currentDesc
riptorEnd == 'w') { | 74 } else if (RuntimeEnabledFeatures::pictureSizesEnabled() && *currentDesc
riptorEnd == 'w') { |
| 75 if (result.foundDescriptor()) | 75 if (result.foundDescriptor()) |
| 76 return false; | 76 return false; |
| 77 result.resourceWidth = charactersToInt(currentDescriptorStart, descr
iptorLength, &isValid); | 77 result.resourceWidth = charactersToInt(currentDescriptorStart, descr
iptorLength, &isValid); |
| 78 if (!isValid || result.resourceWidth < 0) | 78 if (!isValid || result.resourceWidth <= 0) |
| 79 return false; | 79 return false; |
| 80 } | 80 } |
| 81 } | 81 } |
| 82 if (isEmptyDescriptor) | 82 if (isEmptyDescriptor) |
| 83 result.scaleFactor = 1.0; | 83 result.scaleFactor = 1.0; |
| 84 return result.foundDescriptor(); | 84 return result.foundDescriptor(); |
| 85 } | 85 } |
| 86 | 86 |
| 87 // http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content-
1.html#processing-the-image-candidates | 87 // http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content-
1.html#processing-the-image-candidates |
| 88 template<typename CharType> | 88 template<typename CharType> |
| (...skipping 26 matching lines...) Expand all Loading... |
| 115 } else { | 115 } else { |
| 116 // 7. Collect a sequence of characters that are not "," (U+002C) cha
racters, and let that be descriptors. | 116 // 7. Collect a sequence of characters that are not "," (U+002C) cha
racters, and let that be descriptors. |
| 117 skipWhile<CharType, isHTMLSpace<CharType> >(position, attributeEnd); | 117 skipWhile<CharType, isHTMLSpace<CharType> >(position, attributeEnd); |
| 118 const CharType* descriptorsStart = position; | 118 const CharType* descriptorsStart = position; |
| 119 skipUntil<CharType, isComma<CharType> >(position, attributeEnd); | 119 skipUntil<CharType, isComma<CharType> >(position, attributeEnd); |
| 120 const CharType* descriptorsEnd = position; | 120 const CharType* descriptorsEnd = position; |
| 121 if (!parseDescriptors(descriptorsStart, descriptorsEnd, result)) | 121 if (!parseDescriptors(descriptorsStart, descriptorsEnd, result)) |
| 122 continue; | 122 continue; |
| 123 } | 123 } |
| 124 | 124 |
| 125 imageCandidates.append(ImageCandidate(attribute, imageURLStart - attribu
teStart, imageURLEnd - imageURLStart, result)); | 125 ASSERT(imageURLEnd > attributeStart); |
| 126 unsigned imageURLStartingPosition = imageURLStart - attributeStart; |
| 127 ASSERT(imageURLEnd > imageURLStart); |
| 128 unsigned imageURLLength = imageURLEnd - imageURLStart; |
| 129 imageCandidates.append(ImageCandidate(attribute, imageURLStartingPositio
n, imageURLLength, result, ImageCandidate::SrcsetOrigin)); |
| 126 // 11. Return to the step labeled splitting loop. | 130 // 11. Return to the step labeled splitting loop. |
| 127 } | 131 } |
| 128 } | 132 } |
| 129 | 133 |
| 130 static void parseImageCandidatesFromSrcsetAttribute(const String& attribute, Vec
tor<ImageCandidate>& imageCandidates) | 134 static void parseImageCandidatesFromSrcsetAttribute(const String& attribute, Vec
tor<ImageCandidate>& imageCandidates) |
| 131 { | 135 { |
| 132 if (attribute.isNull()) | 136 if (attribute.isNull()) |
| 133 return; | 137 return; |
| 134 | 138 |
| 135 if (attribute.is8Bit()) | 139 if (attribute.is8Bit()) |
| 136 parseImageCandidatesFromSrcsetAttribute<LChar>(attribute, attribute.char
acters8(), attribute.length(), imageCandidates); | 140 parseImageCandidatesFromSrcsetAttribute<LChar>(attribute, attribute.char
acters8(), attribute.length(), imageCandidates); |
| 137 else | 141 else |
| 138 parseImageCandidatesFromSrcsetAttribute<UChar>(attribute, attribute.char
acters16(), attribute.length(), imageCandidates); | 142 parseImageCandidatesFromSrcsetAttribute<UChar>(attribute, attribute.char
acters16(), attribute.length(), imageCandidates); |
| 139 } | 143 } |
| 140 | 144 |
| 141 static ImageCandidate pickBestImageCandidate(float deviceScaleFactor, int effect
iveSize, Vector<ImageCandidate>& imageCandidates) | 145 static ImageCandidate pickBestImageCandidate(float deviceScaleFactor, int effect
iveSize, Vector<ImageCandidate>& imageCandidates) |
| 142 { | 146 { |
| 147 bool ignoreSrc = false; |
| 143 if (imageCandidates.isEmpty()) | 148 if (imageCandidates.isEmpty()) |
| 144 return ImageCandidate(); | 149 return ImageCandidate(); |
| 145 | 150 |
| 146 // http://picture.responsiveimages.org/#normalize-source-densities | 151 // http://picture.responsiveimages.org/#normalize-source-densities |
| 147 for (Vector<ImageCandidate>::iterator it = imageCandidates.begin(); it != im
ageCandidates.end(); ++it) { | 152 for (Vector<ImageCandidate>::iterator it = imageCandidates.begin(); it != im
ageCandidates.end(); ++it) { |
| 148 if (it->scaleFactor() < 0) | 153 if (it->resourceWidth() > 0) { |
| 149 it->setScaleFactor((float)it->resourceWidth() / (float)effectiveSize
); | 154 it->setScaleFactor((float)it->resourceWidth() / (float)effectiveSize
); |
| 155 ignoreSrc = true; |
| 156 } |
| 150 } | 157 } |
| 151 | 158 |
| 152 std::stable_sort(imageCandidates.begin(), imageCandidates.end(), compareBySc
aleFactor); | 159 std::stable_sort(imageCandidates.begin(), imageCandidates.end(), compareBySc
aleFactor); |
| 153 | 160 |
| 154 unsigned i; | 161 unsigned i; |
| 155 for (i = 0; i < imageCandidates.size() - 1; ++i) { | 162 for (i = 0; i < imageCandidates.size() - 1; ++i) { |
| 156 if (imageCandidates[i].scaleFactor() >= deviceScaleFactor) | 163 if ((imageCandidates[i].scaleFactor() >= deviceScaleFactor) && (!ignoreS
rc || !imageCandidates[i].srcOrigin())) |
| 157 break; | 164 break; |
| 158 } | 165 } |
| 159 | 166 |
| 160 float winningScaleFactor = imageCandidates[i].scaleFactor(); | 167 float winningScaleFactor = imageCandidates[i].scaleFactor(); |
| 161 unsigned winner = i; | 168 unsigned winner = i; |
| 162 // 16. If an entry b in candidates has the same associated ... pixel density
as an earlier entry a in candidates, | 169 // 16. If an entry b in candidates has the same associated ... pixel density
as an earlier entry a in candidates, |
| 163 // then remove entry b | 170 // then remove entry b |
| 164 while ((i > 0) && (imageCandidates[--i].scaleFactor() == winningScaleFactor)
) | 171 while ((i > 0) && (imageCandidates[--i].scaleFactor() == winningScaleFactor)
) |
| 165 winner = i; | 172 winner = i; |
| 166 | 173 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 177 } | 184 } |
| 178 | 185 |
| 179 ImageCandidate bestFitSourceForImageAttributes(float deviceScaleFactor, int effe
ctiveSize, const String& srcAttribute, const String& srcsetAttribute) | 186 ImageCandidate bestFitSourceForImageAttributes(float deviceScaleFactor, int effe
ctiveSize, const String& srcAttribute, const String& srcsetAttribute) |
| 180 { | 187 { |
| 181 DescriptorParsingResult defaultResult; | 188 DescriptorParsingResult defaultResult; |
| 182 defaultResult.scaleFactor = 1.0; | 189 defaultResult.scaleFactor = 1.0; |
| 183 | 190 |
| 184 if (srcsetAttribute.isNull()) { | 191 if (srcsetAttribute.isNull()) { |
| 185 if (srcAttribute.isNull()) | 192 if (srcAttribute.isNull()) |
| 186 return ImageCandidate(); | 193 return ImageCandidate(); |
| 187 return ImageCandidate(srcAttribute, 0, srcAttribute.length(), defaultRes
ult); | 194 return ImageCandidate(srcAttribute, 0, srcAttribute.length(), defaultRes
ult, ImageCandidate::SrcOrigin); |
| 188 } | 195 } |
| 189 | 196 |
| 190 Vector<ImageCandidate> imageCandidates; | 197 Vector<ImageCandidate> imageCandidates; |
| 191 | 198 |
| 192 parseImageCandidatesFromSrcsetAttribute(srcsetAttribute, imageCandidates); | 199 parseImageCandidatesFromSrcsetAttribute(srcsetAttribute, imageCandidates); |
| 193 | 200 |
| 194 if (!srcAttribute.isEmpty()) | 201 if (!srcAttribute.isEmpty()) |
| 195 imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.leng
th(), defaultResult)); | 202 imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.leng
th(), defaultResult, ImageCandidate::SrcOrigin)); |
| 196 | 203 |
| 197 return pickBestImageCandidate(deviceScaleFactor, effectiveSize, imageCandida
tes); | 204 return pickBestImageCandidate(deviceScaleFactor, effectiveSize, imageCandida
tes); |
| 198 } | 205 } |
| 199 | 206 |
| 200 String bestFitSourceForImageAttributes(float deviceScaleFactor, int effectiveSiz
e, const String& srcAttribute, ImageCandidate& srcsetImageCandidate) | 207 String bestFitSourceForImageAttributes(float deviceScaleFactor, int effectiveSiz
e, const String& srcAttribute, ImageCandidate& srcsetImageCandidate) |
| 201 { | 208 { |
| 202 DescriptorParsingResult defaultResult; | 209 DescriptorParsingResult defaultResult; |
| 203 defaultResult.scaleFactor = 1.0; | 210 defaultResult.scaleFactor = 1.0; |
| 204 | 211 |
| 205 if (srcsetImageCandidate.isEmpty()) | 212 if (srcsetImageCandidate.isEmpty()) |
| 206 return srcAttribute; | 213 return srcAttribute; |
| 207 | 214 |
| 208 Vector<ImageCandidate> imageCandidates; | 215 Vector<ImageCandidate> imageCandidates; |
| 209 imageCandidates.append(srcsetImageCandidate); | 216 imageCandidates.append(srcsetImageCandidate); |
| 210 | 217 |
| 211 if (!srcAttribute.isEmpty()) | 218 if (!srcAttribute.isEmpty()) |
| 212 imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.leng
th(), defaultResult)); | 219 imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.leng
th(), defaultResult, ImageCandidate::SrcOrigin)); |
| 213 | 220 |
| 214 return pickBestImageCandidate(deviceScaleFactor, effectiveSize, imageCandida
tes).toString(); | 221 return pickBestImageCandidate(deviceScaleFactor, effectiveSize, imageCandida
tes).toString(); |
| 215 } | 222 } |
| 216 | 223 |
| 217 } | 224 } |
| OLD | NEW |