diff options
-rw-r--r-- | core/fxge/cfx_color.cpp | 9 | ||||
-rw-r--r-- | core/fxge/cfx_color.h | 1 | ||||
-rw-r--r-- | fxjs/cjs_color.cpp | 20 | ||||
-rw-r--r-- | testing/resources/javascript/color_methods.in | 133 | ||||
-rw-r--r-- | testing/resources/javascript/color_methods_expected.txt | 57 |
5 files changed, 214 insertions, 6 deletions
diff --git a/core/fxge/cfx_color.cpp b/core/fxge/cfx_color.cpp index e4d89dc2ff..a19f040e51 100644 --- a/core/fxge/cfx_color.cpp +++ b/core/fxge/cfx_color.cpp @@ -11,6 +11,15 @@ #include "core/fpdfapi/parser/cpdf_array.h" #include "core/fpdfdoc/cpdf_defaultappearance.h" +// Color types are orded by increasing number of components so we can +// choose a best color type during some conversions. +static_assert(CFX_Color::kTransparent < CFX_Color::kGray, + "color type values must be ordered"); +static_assert(CFX_Color::kGray < CFX_Color::kRGB, + "color type values must be ordered"); +static_assert(CFX_Color::kRGB < CFX_Color::kCMYK, + "color type values must be ordered"); + namespace { bool InRange(float comp) { diff --git a/core/fxge/cfx_color.h b/core/fxge/cfx_color.h index d6fabad989..1dd512a42d 100644 --- a/core/fxge/cfx_color.h +++ b/core/fxge/cfx_color.h @@ -14,6 +14,7 @@ struct CFX_Color { static CFX_Color ParseColor(const CPDF_Array& array); static CFX_Color ParseColor(const ByteString& str); + // Ordered by increasing number of components. enum Type { kTransparent = 0, kGray, kRGB, kCMYK }; explicit CFX_Color(FX_COLORREF ref) diff --git a/fxjs/cjs_color.cpp b/fxjs/cjs_color.cpp index 7ce5c2937c..0d4065eb6a 100644 --- a/fxjs/cjs_color.cpp +++ b/fxjs/cjs_color.cpp @@ -6,6 +6,7 @@ #include "fxjs/cjs_color.h" +#include <algorithm> #include <vector> #include "core/fxge/cfx_color.h" @@ -271,10 +272,12 @@ CJS_Result CJS_Color::SetPropertyHelper(CJS_Runtime* pRuntime, CJS_Result CJS_Color::convert(CJS_Runtime* pRuntime, const std::vector<v8::Local<v8::Value>>& params) { - int iSize = params.size(); - if (iSize < 2 || params[0].IsEmpty() || !params[0]->IsArray()) + if (params.size() < 2) return CJS_Result::Failure(JSMessage::kParamError); + if (params[0].IsEmpty() || !params[0]->IsArray()) + return CJS_Result::Failure(JSMessage::kTypeError); + WideString sDestSpace = pRuntime->ToWideString(params[1]); int nColorType = CFX_Color::kTransparent; if (sDestSpace == L"T") @@ -298,9 +301,12 @@ CJS_Result CJS_Color::convert(CJS_Runtime* pRuntime, CJS_Result CJS_Color::equal(CJS_Runtime* pRuntime, const std::vector<v8::Local<v8::Value>>& params) { - if (params.size() < 2 || params[0].IsEmpty() || !params[0]->IsArray() || - params[1].IsEmpty() || !params[1]->IsArray()) { + if (params.size() < 2) return CJS_Result::Failure(JSMessage::kParamError); + + if (params[0].IsEmpty() || !params[0]->IsArray() || params[1].IsEmpty() || + !params[1]->IsArray()) { + return CJS_Result::Failure(JSMessage::kTypeError); } CFX_Color color1 = @@ -308,6 +314,8 @@ CJS_Result CJS_Color::equal(CJS_Runtime* pRuntime, CFX_Color color2 = ConvertArrayToPWLColor(pRuntime, pRuntime->ToArray(params[1])); - color1 = color1.ConvertColorType(color2.nColorType); - return CJS_Result::Success(pRuntime->NewBoolean(color1 == color2)); + // Relies on higher values having more components. + int32_t best = std::max(color1.nColorType, color2.nColorType); + return CJS_Result::Success(pRuntime->NewBoolean( + color1.ConvertColorType(best) == color2.ConvertColorType(best))); } diff --git a/testing/resources/javascript/color_methods.in b/testing/resources/javascript/color_methods.in new file mode 100644 index 0000000000..1268657650 --- /dev/null +++ b/testing/resources/javascript/color_methods.in @@ -0,0 +1,133 @@ +{{header}} +{{object 1 0}} << + /Type /Catalog + /Pages 2 0 R + /OpenAction 10 0 R +>> +endobj +{{object 2 0}} << + /Type /Pages + /Count 1 + /Kids [ + 3 0 R + ] +>> +endobj +% Page number 0. +{{object 3 0}} << + /Type /Page + /Parent 2 0 R + /MediaBox [0 0 612 792] +>> +endobj +% OpenAction action +{{object 10 0}} << + /Type /Action + /S /JavaScript + /JS 11 0 R +>> +endobj +% JS program to exexute +{{object 11 0}} << + {{streamlen}} +>> +stream +function expect(str, expected) { + try { + var result = eval(str); + if (result == expected) { + app.alert('PASS: ' + str + ' = ' + result); + } else { + app.alert('FAIL: ' + str + ' = ' + result + ', expected = ' + expected); + } + } catch (e) { + app.alert('ERROR: ' + e.toString()); + } +} + +function expectError(str) { + try { + var result = eval(str); + app.alert('FAIL: ' + str + ' = ' + result + ', expected to throw error'); + } catch (e) { + app.alert('PASS: ' + str + ' threw error ' + e.toString()); + } +} + +try { + expectError("color.convert()"); + expectError("color.convert(1)"); + expectError("color.convert(undefined, 'RGB')"); + expectError("color.convert('BOGUS', 'RGB')"); + expectError("color.convert('{}', 'RGB')"); + + // Can't convert transparent into anything else. + expect("color.convert(['T'], 'BOGUS')", "T"); + expect("color.convert(['T'], 'T')", "T"); + expect("color.convert(['T'], 'G')", "T"); + expect("color.convert(['T'], 'RGB')", "T"); + expect("color.convert(['T'], 'CMYK')", "T"); + + expect("color.convert(['G', 0.50], 'BOGUS')", "T"); + expect("color.convert(['G', 0.50], 'T')", "T"); + expect("color.convert(['G', 0.50], 'G')", "G,0.5"); + expect("color.convert(['G', 0.50], 'RGB')", "RGB,0.5,0.5,0.5"); + expect("color.convert(['G', 0.50], 'CMYK')", "CMYK,0,0,0,0.5"); + + expect("color.convert(['RGB', 0.25, 0.50, 0.75], 'BOGUS')", "T"); + expect("color.convert(['RGB', 0.25, 0.50, 0.75], 'T')", "T"); + expect("color.convert(['RGB', 1.00, 1.00, 1.00], 'G')", "G,1"); + expect("color.convert(['RGB', 0.25, 0.50, 0.75], 'RGB')", "RGB,0.25,0.5,0.75"); + expect("color.convert(['RGB', 0.25, 0.50, 0.75], 'CMYK')", "CMYK,0.75,0.5,0.25,0.25"); + + expect("color.convert(['CMYK',0.25,0.25,0.25,0.50], 'BOGUS')", "T"); + expect("color.convert(['CMYK',0.25,0.25,0.25,0.50], 'T')", "T"); + expect("color.convert(['CMYK',0.25,0.25,0.25,0.50], 'G')", "G,0.25"); + expect("color.convert(['CMYK',0.25,0.25,0.25,0.50], 'RGB')", "RGB,0.25,0.25,0.25"); + expect("color.convert(['CMYK',0.25,0.25,0.25,0.50], 'CMYK')", "CMYK,0.25,0.25,0.25,0.5"); + + expectError("color.equal()"); + expectError("color.equal(1)"); + expectError("color.equal(undefined, undefined)"); + expectError("color.equal(undefined, 'BOGUS')"); + expectError("color.equal('BOGUS', 'BOGUS')"); + expectError("color.equal('BOGUS', ['T'])"); + expectError("color.equal(['T'], 'BOGUS')"); + + expect("color.equal(['T'], ['T'])", true); + expect("color.equal(['T'], ['G', 0])", false); + expect("color.equal(['T'], ['RGB', 0, 0, 0])", false); + expect("color.equal(['T'], ['CMYK', 0, 0, 0, 0])", false); + + expect("color.equal(['G', 0.50], ['T'])", false); + expect("color.equal(['G', 0.50], ['G', 0])", false); + expect("color.equal(['G', 0.50], ['G', 0.50])", true); + expect("color.equal(['G', 0.50], ['RGB', 0, 0, 0])", false); + expect("color.equal(['G', 0.50], ['RGB', 0.50, 0.50, 0.50])", true); + expect("color.equal(['G', 0.50], ['CMYK', 0, 0, 0, 0])", false); + expect("color.equal(['G', 0.50], ['CMYK', 0, 0, 0, 0.50])", true); + + expect("color.equal(['RGB', 0.25, 0.25, 0.25], ['T'])", false); + expect("color.equal(['RGB', 0.25, 0.25, 0.25], ['G', 0])", false); + expect("color.equal(['RGB', 0.25, 0.25, 0.25], ['G', 0.25])", true); + expect("color.equal(['RGB', 0.25, 0.25, 0.25], ['RGB', 0, 0, 0])", false); + expect("color.equal(['RGB', 0.25, 0.25, 0.25], ['RGB', 0.25, 0.25, 0.25])", true); + expect("color.equal(['RGB', 0.25, 0.25, 0.25], ['CMYK', 0, 0, 0, 0])", false); + expect("color.equal(['RGB', 0.25, 0.25, 0.25], ['CMYK', 0.75, 0.75, 0.75, 0.75])", true); + + expect("color.equal(['CMYK', 0.25, 0.25, 0.25, 0.50], ['T'])", false); + expect("color.equal(['CMYK', 0.00, 0.25, 0.25, 0.50], ['G', 0])", false); + expect("color.equal(['CMYK', 0.00, 0.00, 0.00, 0.50], ['G', 0.50])", true); + expect("color.equal(['CMYK', 0.75, 0.50, 0.25, 0.25], ['RGB', 0, 0, 0])", false); + expect("color.equal(['CMYK', 0.75, 0.50, 0.25, 0.25], ['RGB', 0.25, 0.50, 0.75])", true); + expect("color.equal(['CMYK', 0.25, 0.25, 0.25, 0.50], ['CMYK', 0, 0, 0, 0])", false); + expect("color.equal(['CMYK', 0.25, 0.25, 0.25, 0.50], ['CMYK', 0.25, 0.25, 0.25, 0.50])", true); +} catch (e) { + app.alert("Truly unexpected error: " + e); +} +endstream +endobj +{{xref}} +{{trailer}} +{{startxref}} +%%EOF diff --git a/testing/resources/javascript/color_methods_expected.txt b/testing/resources/javascript/color_methods_expected.txt new file mode 100644 index 0000000000..2552a5e4ba --- /dev/null +++ b/testing/resources/javascript/color_methods_expected.txt @@ -0,0 +1,57 @@ +Alert: PASS: color.convert() threw error color.convert: Incorrect number of parameters passed to function. +Alert: PASS: color.convert(1) threw error color.convert: Incorrect number of parameters passed to function. +Alert: PASS: color.convert(undefined, 'RGB') threw error color.convert: Incorrect parameter type. +Alert: PASS: color.convert('BOGUS', 'RGB') threw error color.convert: Incorrect parameter type. +Alert: PASS: color.convert('{}', 'RGB') threw error color.convert: Incorrect parameter type. +Alert: PASS: color.convert(['T'], 'BOGUS') = T +Alert: PASS: color.convert(['T'], 'T') = T +Alert: PASS: color.convert(['T'], 'G') = T +Alert: PASS: color.convert(['T'], 'RGB') = T +Alert: PASS: color.convert(['T'], 'CMYK') = T +Alert: PASS: color.convert(['G', 0.50], 'BOGUS') = T +Alert: PASS: color.convert(['G', 0.50], 'T') = T +Alert: PASS: color.convert(['G', 0.50], 'G') = G,0.5 +Alert: PASS: color.convert(['G', 0.50], 'RGB') = RGB,0.5,0.5,0.5 +Alert: PASS: color.convert(['G', 0.50], 'CMYK') = CMYK,0,0,0,0.5 +Alert: PASS: color.convert(['RGB', 0.25, 0.50, 0.75], 'BOGUS') = T +Alert: PASS: color.convert(['RGB', 0.25, 0.50, 0.75], 'T') = T +Alert: PASS: color.convert(['RGB', 1.00, 1.00, 1.00], 'G') = G,1 +Alert: PASS: color.convert(['RGB', 0.25, 0.50, 0.75], 'RGB') = RGB,0.25,0.5,0.75 +Alert: PASS: color.convert(['RGB', 0.25, 0.50, 0.75], 'CMYK') = CMYK,0.75,0.5,0.25,0.25 +Alert: PASS: color.convert(['CMYK',0.25,0.25,0.25,0.50], 'BOGUS') = T +Alert: PASS: color.convert(['CMYK',0.25,0.25,0.25,0.50], 'T') = T +Alert: PASS: color.convert(['CMYK',0.25,0.25,0.25,0.50], 'G') = G,0.25 +Alert: PASS: color.convert(['CMYK',0.25,0.25,0.25,0.50], 'RGB') = RGB,0.25,0.25,0.25 +Alert: PASS: color.convert(['CMYK',0.25,0.25,0.25,0.50], 'CMYK') = CMYK,0.25,0.25,0.25,0.5 +Alert: PASS: color.equal() threw error color.equal: Incorrect number of parameters passed to function. +Alert: PASS: color.equal(1) threw error color.equal: Incorrect number of parameters passed to function. +Alert: PASS: color.equal(undefined, undefined) threw error color.equal: Incorrect parameter type. +Alert: PASS: color.equal(undefined, 'BOGUS') threw error color.equal: Incorrect parameter type. +Alert: PASS: color.equal('BOGUS', 'BOGUS') threw error color.equal: Incorrect parameter type. +Alert: PASS: color.equal('BOGUS', ['T']) threw error color.equal: Incorrect parameter type. +Alert: PASS: color.equal(['T'], 'BOGUS') threw error color.equal: Incorrect parameter type. +Alert: PASS: color.equal(['T'], ['T']) = true +Alert: PASS: color.equal(['T'], ['G', 0]) = false +Alert: PASS: color.equal(['T'], ['RGB', 0, 0, 0]) = false +Alert: PASS: color.equal(['T'], ['CMYK', 0, 0, 0, 0]) = false +Alert: PASS: color.equal(['G', 0.50], ['T']) = false +Alert: PASS: color.equal(['G', 0.50], ['G', 0]) = false +Alert: PASS: color.equal(['G', 0.50], ['G', 0.50]) = true +Alert: PASS: color.equal(['G', 0.50], ['RGB', 0, 0, 0]) = false +Alert: PASS: color.equal(['G', 0.50], ['RGB', 0.50, 0.50, 0.50]) = true +Alert: PASS: color.equal(['G', 0.50], ['CMYK', 0, 0, 0, 0]) = false +Alert: PASS: color.equal(['G', 0.50], ['CMYK', 0, 0, 0, 0.50]) = true +Alert: PASS: color.equal(['RGB', 0.25, 0.25, 0.25], ['T']) = false +Alert: PASS: color.equal(['RGB', 0.25, 0.25, 0.25], ['G', 0]) = false +Alert: PASS: color.equal(['RGB', 0.25, 0.25, 0.25], ['G', 0.25]) = true +Alert: PASS: color.equal(['RGB', 0.25, 0.25, 0.25], ['RGB', 0, 0, 0]) = false +Alert: PASS: color.equal(['RGB', 0.25, 0.25, 0.25], ['RGB', 0.25, 0.25, 0.25]) = true +Alert: PASS: color.equal(['RGB', 0.25, 0.25, 0.25], ['CMYK', 0, 0, 0, 0]) = false +Alert: PASS: color.equal(['RGB', 0.25, 0.25, 0.25], ['CMYK', 0.75, 0.75, 0.75, 0.75]) = true +Alert: PASS: color.equal(['CMYK', 0.25, 0.25, 0.25, 0.50], ['T']) = false +Alert: PASS: color.equal(['CMYK', 0.00, 0.25, 0.25, 0.50], ['G', 0]) = false +Alert: PASS: color.equal(['CMYK', 0.00, 0.00, 0.00, 0.50], ['G', 0.50]) = true +Alert: PASS: color.equal(['CMYK', 0.75, 0.50, 0.25, 0.25], ['RGB', 0, 0, 0]) = false +Alert: PASS: color.equal(['CMYK', 0.75, 0.50, 0.25, 0.25], ['RGB', 0.25, 0.50, 0.75]) = true +Alert: PASS: color.equal(['CMYK', 0.25, 0.25, 0.25, 0.50], ['CMYK', 0, 0, 0, 0]) = false +Alert: PASS: color.equal(['CMYK', 0.25, 0.25, 0.25, 0.50], ['CMYK', 0.25, 0.25, 0.25, 0.50]) = true |