summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/fxge/cfx_color.cpp9
-rw-r--r--core/fxge/cfx_color.h1
-rw-r--r--fxjs/cjs_color.cpp20
-rw-r--r--testing/resources/javascript/color_methods.in133
-rw-r--r--testing/resources/javascript/color_methods_expected.txt57
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