| // Copyright 2014 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/cloud_devices/common/printer_description.h" |
| |
| #include <stddef.h> |
| |
| #include <algorithm> |
| #include <memory> |
| #include <ostream> |
| #include <string> |
| #include <utility> |
| |
| #include "base/check.h" |
| #include "base/json/json_reader.h" |
| #include "base/json/json_writer.h" |
| #include "base/notreached.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/string_util.h" |
| #include "base/values.h" |
| #include "build/build_config.h" |
| #include "components/cloud_devices/common/cloud_device_description_consts.h" |
| #include "components/cloud_devices/common/description_items_inl.h" |
| #include "ui/gfx/geometry/rect.h" |
| #include "ui/gfx/geometry/size.h" |
| |
| namespace cloud_devices { |
| |
| namespace printer { |
| |
| namespace { |
| |
| constexpr int32_t kMaxPageNumber = 1000000; |
| |
| constexpr char kSectionPrint[] = "print"; |
| constexpr char kSectionPrinter[] = "printer"; |
| |
| constexpr char kKeyCustomDisplayName[] = "custom_display_name"; |
| constexpr char kKeyContentType[] = "content_type"; |
| constexpr char kKeyDisplayName[] = "display_name"; |
| constexpr char kKeyId[] = "id"; |
| constexpr char kKeyName[] = "name"; |
| constexpr char kKeyType[] = "type"; |
| constexpr char kKeyValue[] = "value"; |
| constexpr char kKeyValueType[] = "value_type"; |
| constexpr char kKeyVendorId[] = "vendor_id"; |
| |
| // extern is required to be used in templates. |
| extern constexpr char kOptionCollate[] = "collate"; |
| extern constexpr char kOptionColor[] = "color"; |
| extern constexpr char kOptionContentType[] = "supported_content_type"; |
| extern constexpr char kOptionCopies[] = "copies"; |
| extern constexpr char kOptionDpi[] = "dpi"; |
| extern constexpr char kOptionDuplex[] = "duplex"; |
| extern constexpr char kOptionFitToPage[] = "fit_to_page"; |
| extern constexpr char kOptionMargins[] = "margins"; |
| extern constexpr char kOptionMediaSize[] = "media_size"; |
| extern constexpr char kOptionMediaType[] = "media_type"; |
| extern constexpr char kOptionPageOrientation[] = "page_orientation"; |
| extern constexpr char kOptionPageRange[] = "page_range"; |
| extern constexpr char kOptionReverse[] = "reverse_order"; |
| extern constexpr char kOptionPwgRasterConfig[] = "pwg_raster_config"; |
| extern constexpr char kOptionRangeCapability[] = "range_cap"; |
| extern constexpr char kOptionSelectCapability[] = "select_cap"; |
| extern constexpr char kOptionTypedValueCapability[] = "typed_value_cap"; |
| extern constexpr char kOptionVendorCapability[] = "vendor_capability"; |
| extern constexpr char kOptionVendorItem[] = "vendor_ticket_item"; |
| #if BUILDFLAG(IS_CHROMEOS) |
| extern constexpr char kOptionPin[] = "pin"; |
| #endif // BUILDFLAG(IS_CHROMEOS) |
| |
| constexpr char kMarginBottom[] = "bottom_microns"; |
| constexpr char kMarginLeft[] = "left_microns"; |
| constexpr char kMarginRight[] = "right_microns"; |
| constexpr char kMarginTop[] = "top_microns"; |
| |
| constexpr char kDpiHorizontal[] = "horizontal_dpi"; |
| constexpr char kDpiVertical[] = "vertical_dpi"; |
| |
| constexpr char kMediaWidth[] = "width_microns"; |
| constexpr char kMediaHeight[] = "height_microns"; |
| constexpr char kMediaIsContinuous[] = "is_continuous_feed"; |
| constexpr char kMediaImageableAreaLeft[] = "imageable_area_left_microns"; |
| constexpr char kMediaImageableAreaBottom[] = "imageable_area_bottom_microns"; |
| constexpr char kMediaImageableAreaRight[] = "imageable_area_right_microns"; |
| constexpr char kMediaImageableAreaTop[] = "imageable_area_top_microns"; |
| constexpr char kMediaMinHeight[] = "min_height_microns"; |
| constexpr char kMediaMaxHeight[] = "max_height_microns"; |
| constexpr char kMediaHasBorderlessVariant[] = "has_borderless_variant"; |
| |
| constexpr char kPageRangeInterval[] = "interval"; |
| constexpr char kPageRangeEnd[] = "end"; |
| constexpr char kPageRangeStart[] = "start"; |
| |
| constexpr char kPwgRasterDocumentTypeSupported[] = "document_type_supported"; |
| constexpr char kPwgRasterDocumentSheetBack[] = "document_sheet_back"; |
| constexpr char kPwgRasterReverseOrderStreaming[] = "reverse_order_streaming"; |
| constexpr char kPwgRasterRotateAllPages[] = "rotate_all_pages"; |
| |
| constexpr char kMinValue[] = "min"; |
| constexpr char kMaxValue[] = "max"; |
| constexpr char kDefaultValue[] = "default"; |
| |
| #if BUILDFLAG(IS_CHROMEOS) |
| constexpr char kPinSupported[] = "supported"; |
| #endif // BUILDFLAG(IS_CHROMEOS) |
| |
| constexpr char kTypeRangeVendorCapabilityFloat[] = "FLOAT"; |
| constexpr char kTypeRangeVendorCapabilityInteger[] = "INTEGER"; |
| |
| constexpr char kTypeTypedValueVendorCapabilityBoolean[] = "BOOLEAN"; |
| constexpr char kTypeTypedValueVendorCapabilityFloat[] = "FLOAT"; |
| constexpr char kTypeTypedValueVendorCapabilityInteger[] = "INTEGER"; |
| constexpr char kTypeTypedValueVendorCapabilityString[] = "STRING"; |
| |
| constexpr char kTypeVendorCapabilityRange[] = "RANGE"; |
| constexpr char kTypeVendorCapabilitySelect[] = "SELECT"; |
| constexpr char kTypeVendorCapabilityTypedValue[] = "TYPED_VALUE"; |
| |
| constexpr char kTypeColorColor[] = "STANDARD_COLOR"; |
| constexpr char kTypeColorMonochrome[] = "STANDARD_MONOCHROME"; |
| constexpr char kTypeColorCustomColor[] = "CUSTOM_COLOR"; |
| constexpr char kTypeColorCustomMonochrome[] = "CUSTOM_MONOCHROME"; |
| constexpr char kTypeColorAuto[] = "AUTO"; |
| |
| constexpr char kTypeDuplexLongEdge[] = "LONG_EDGE"; |
| constexpr char kTypeDuplexNoDuplex[] = "NO_DUPLEX"; |
| constexpr char kTypeDuplexShortEdge[] = "SHORT_EDGE"; |
| |
| constexpr char kTypeFitToPageAuto[] = "AUTO"; |
| constexpr char kTypeFitToPageAutoFit[] = "AUTO_FIT"; |
| constexpr char kTypeFitToPageFill[] = "FILL"; |
| constexpr char kTypeFitToPageFit[] = "FIT"; |
| constexpr char kTypeFitToPageNone[] = "NONE"; |
| |
| constexpr char kTypeOrientationAuto[] = "AUTO"; |
| constexpr char kTypeOrientationLandscape[] = "LANDSCAPE"; |
| constexpr char kTypeOrientationPortrait[] = "PORTRAIT"; |
| |
| constexpr char kTypeDocumentSupportedTypeSRGB8[] = "SRGB_8"; |
| constexpr char kTypeDocumentSupportedTypeSGRAY8[] = "SGRAY_8"; |
| |
| constexpr char kTypeDocumentSheetBackNormal[] = "NORMAL"; |
| constexpr char kTypeDocumentSheetBackRotated[] = "ROTATED"; |
| constexpr char kTypeDocumentSheetBackManualTumble[] = "MANUAL_TUMBLE"; |
| constexpr char kTypeDocumentSheetBackFlipped[] = "FLIPPED"; |
| |
| constexpr struct RangeVendorCapabilityTypeNames { |
| RangeVendorCapability::ValueType id; |
| const char* json_name; |
| } kRangeVendorCapabilityTypeNames[] = { |
| {RangeVendorCapability::ValueType::FLOAT, kTypeRangeVendorCapabilityFloat}, |
| {RangeVendorCapability::ValueType::INTEGER, |
| kTypeRangeVendorCapabilityInteger}, |
| }; |
| |
| constexpr struct TypedValueVendorCapabilityTypeNames { |
| TypedValueVendorCapability::ValueType id; |
| const char* json_name; |
| } kTypedValueVendorCapabilityTypeNames[] = { |
| {TypedValueVendorCapability::ValueType::BOOLEAN, |
| kTypeTypedValueVendorCapabilityBoolean}, |
| {TypedValueVendorCapability::ValueType::FLOAT, |
| kTypeTypedValueVendorCapabilityFloat}, |
| {TypedValueVendorCapability::ValueType::INTEGER, |
| kTypeTypedValueVendorCapabilityInteger}, |
| {TypedValueVendorCapability::ValueType::STRING, |
| kTypeTypedValueVendorCapabilityString}, |
| }; |
| |
| constexpr struct VendorCapabilityTypeNames { |
| VendorCapability::Type id; |
| const char* json_name; |
| } kVendorCapabilityTypeNames[] = { |
| {VendorCapability::Type::RANGE, kTypeVendorCapabilityRange}, |
| {VendorCapability::Type::SELECT, kTypeVendorCapabilitySelect}, |
| {VendorCapability::Type::TYPED_VALUE, kTypeVendorCapabilityTypedValue}, |
| }; |
| |
| constexpr struct ColorNames { |
| ColorType id; |
| const char* const json_name; |
| } kColorNames[] = { |
| {ColorType::STANDARD_COLOR, kTypeColorColor}, |
| {ColorType::STANDARD_MONOCHROME, kTypeColorMonochrome}, |
| {ColorType::CUSTOM_COLOR, kTypeColorCustomColor}, |
| {ColorType::CUSTOM_MONOCHROME, kTypeColorCustomMonochrome}, |
| {ColorType::AUTO_COLOR, kTypeColorAuto}, |
| }; |
| |
| constexpr struct DuplexNames { |
| DuplexType id; |
| const char* const json_name; |
| } kDuplexNames[] = { |
| {DuplexType::NO_DUPLEX, kTypeDuplexNoDuplex}, |
| {DuplexType::LONG_EDGE, kTypeDuplexLongEdge}, |
| {DuplexType::SHORT_EDGE, kTypeDuplexShortEdge}, |
| }; |
| |
| constexpr struct OrientationNames { |
| OrientationType id; |
| const char* const json_name; |
| } kOrientationNames[] = { |
| {OrientationType::PORTRAIT, kTypeOrientationPortrait}, |
| {OrientationType::LANDSCAPE, kTypeOrientationLandscape}, |
| {OrientationType::AUTO_ORIENTATION, kTypeOrientationAuto}, |
| }; |
| |
| constexpr struct FitToPageNames { |
| FitToPageType id; |
| const char* const json_name; |
| } kFitToPageNames[] = { |
| {FitToPageType::AUTO, kTypeFitToPageAuto}, |
| {FitToPageType::AUTO_FIT, kTypeFitToPageAutoFit}, |
| {FitToPageType::FILL, kTypeFitToPageFill}, |
| {FitToPageType::FIT, kTypeFitToPageFit}, |
| {FitToPageType::NONE, kTypeFitToPageNone}, |
| }; |
| |
| constexpr struct DocumentSheetBackNames { |
| DocumentSheetBack id; |
| const char* const json_name; |
| } kDocumentSheetBackNames[] = { |
| {DocumentSheetBack::NORMAL, kTypeDocumentSheetBackNormal}, |
| {DocumentSheetBack::ROTATED, kTypeDocumentSheetBackRotated}, |
| {DocumentSheetBack::MANUAL_TUMBLE, kTypeDocumentSheetBackManualTumble}, |
| {DocumentSheetBack::FLIPPED, kTypeDocumentSheetBackFlipped}}; |
| |
| constexpr int32_t kInchToUm = 25400; |
| constexpr int32_t kMmToUm = 1000; |
| constexpr int32_t kSizeThresholdUm = 1000; |
| |
| constexpr size_t kEnumClassPrefixLen = std::size("MediaSize::") - 1; |
| |
| // Json name of media type is constructed by removing "MediaSize::" enum class |
| // prefix from it. |
| #define MAP_CLOUD_PRINT_MEDIA_SIZE(type, width, height, unit_um) \ |
| { \ |
| type, &#type[kEnumClassPrefixLen], \ |
| gfx::Size(static_cast<int>(width * unit_um + 0.5), \ |
| static_cast<int>(height * unit_um + 0.5)) \ |
| } |
| |
| constexpr struct MediaDefinition { |
| MediaSize id; |
| const char* const json_name; |
| gfx::Size size_um; |
| } kMediaDefinitions[] = { |
| {MediaSize::CUSTOM_MEDIA, "CUSTOM", gfx::Size()}, |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_INDEX_3X5, 3, 5, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_PERSONAL, 3.625f, 6.5f, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_MONARCH, 3.875f, 7.5f, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_NUMBER_9, |
| 3.875f, |
| 8.875f, |
| kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_INDEX_4X6, 4, 6, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_NUMBER_10, |
| 4.125f, |
| 9.5f, |
| kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_A2, 4.375f, 5.75f, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_NUMBER_11, |
| 4.5f, |
| 10.375f, |
| kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_NUMBER_12, 4.75f, 11, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_5X7, 5, 7, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_INDEX_5X8, 5, 8, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_NUMBER_14, 5, 11.5f, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_INVOICE, 5.5f, 8.5f, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_INDEX_4X6_EXT, 6, 8, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_6X9, 6, 9, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_C5, 6.5f, 9.5f, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_7X9, 7, 9, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_EXECUTIVE, |
| 7.25f, |
| 10.5f, |
| kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_GOVT_LETTER, 8, 10, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_GOVT_LEGAL, 8, 13, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_QUARTO, 8.5f, 10.83f, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_LETTER, 8.5f, 11, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_FANFOLD_EUR, 8.5f, 12, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_LETTER_PLUS, |
| 8.5f, |
| 12.69f, |
| kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_FOOLSCAP, 8.5f, 13, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_LEGAL, 8.5f, 14, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_SUPER_A, 8.94f, 14, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_9X11, 9, 11, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_ARCH_A, 9, 12, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_LETTER_EXTRA, 9.5f, 12, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_LEGAL_EXTRA, 9.5f, 15, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_10X11, 10, 11, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_10X13, 10, 13, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_10X14, 10, 14, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_10X15, 10, 15, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_11X12, 11, 12, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_EDP, 11, 14, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_FANFOLD_US, |
| 11, |
| 14.875f, |
| kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_11X15, 11, 15, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_LEDGER, 11, 17, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_EUR_EDP, 12, 14, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_ARCH_B, 12, 18, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_12X19, 12, 19, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_B_PLUS, 12, 19.17f, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_SUPER_B, 13, 19, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_C, 17, 22, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_ARCH_C, 18, 24, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_D, 22, 34, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_ARCH_D, 24, 36, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_ASME_F, 28, 40, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_WIDE_FORMAT, 30, 42, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_E, 34, 44, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_ARCH_E, 36, 48, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::NA_F, 44, 68, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ROC_16K, 7.75f, 10.75f, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ROC_8K, 10.75f, 15.5f, kInchToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::PRC_32K, 97, 151, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::PRC_1, 102, 165, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::PRC_2, 102, 176, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::PRC_4, 110, 208, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::PRC_5, 110, 220, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::PRC_8, 120, 309, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::PRC_6, 120, 230, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::PRC_3, 125, 176, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::PRC_16K, 146, 215, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::PRC_7, 160, 230, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::OM_JUURO_KU_KAI, 198, 275, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::OM_PA_KAI, 267, 389, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::OM_DAI_PA_KAI, 275, 395, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::PRC_10, 324, 458, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A10, 26, 37, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A9, 37, 52, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A8, 52, 74, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A7, 74, 105, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A6, 105, 148, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A5, 148, 210, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A5_EXTRA, 174, 235, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A4, 210, 297, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A4_TAB, 225, 297, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A4_EXTRA, 235, 322, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A3, 297, 420, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A4X3, 297, 630, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A4X4, 297, 841, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A4X5, 297, 1051, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A4X6, 297, 1261, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A4X7, 297, 1471, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A4X8, 297, 1682, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A4X9, 297, 1892, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A3_EXTRA, 322, 445, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A2, 420, 594, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A3X3, 420, 891, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A3X4, 420, 1189, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A3X5, 420, 1486, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A3X6, 420, 1783, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A3X7, 420, 2080, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A1, 594, 841, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A2X3, 594, 1261, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A2X4, 594, 1682, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A2X5, 594, 2102, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A0, 841, 1189, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A1X3, 841, 1783, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A1X4, 841, 2378, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_2A0, 1189, 1682, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_A0X3, 1189, 2523, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_B10, 31, 44, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_B9, 44, 62, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_B8, 62, 88, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_B7, 88, 125, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_B6, 125, 176, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_B6C4, 125, 324, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_B5, 176, 250, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_B5_EXTRA, 201, 276, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_B4, 250, 353, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_B3, 353, 500, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_B2, 500, 707, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_B1, 707, 1000, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_B0, 1000, 1414, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_C10, 28, 40, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_C9, 40, 57, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_C8, 57, 81, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_C7, 81, 114, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_C7C6, 81, 162, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_C6, 114, 162, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_C6C5, 114, 229, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_C5, 162, 229, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_C4, 229, 324, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_C3, 324, 458, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_C2, 458, 648, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_C1, 648, 917, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_C0, 917, 1297, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_DL, 110, 220, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_RA2, 430, 610, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_SRA2, 450, 640, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_RA1, 610, 860, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_SRA1, 640, 900, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_RA0, 860, 1220, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::ISO_SRA0, 900, 1280, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::JIS_B10, 32, 45, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::JIS_B9, 45, 64, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::JIS_B8, 64, 91, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::JIS_B7, 91, 128, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::JIS_B6, 128, 182, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::JIS_B5, 182, 257, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::JIS_B4, 257, 364, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::JIS_B3, 364, 515, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::JIS_B2, 515, 728, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::JIS_B1, 728, 1030, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::JIS_B0, 1030, 1456, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::JIS_EXEC, 216, 330, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::JPN_CHOU4, 90, 205, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::JPN_HAGAKI, 100, 148, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::JPN_YOU4, 105, 235, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::JPN_CHOU2, 111.1f, 146, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::JPN_CHOU3, 120, 235, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::JPN_OUFUKU, 148, 200, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::JPN_KAHU, 240, 322.1f, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::JPN_KAKU2, 240, 332, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::OM_SMALL_PHOTO, 100, 150, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::OM_ITALIAN, 110, 230, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::OM_POSTFIX, 114, 229, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::OM_LARGE_PHOTO, 200, 300, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::OM_FOLIO, 210, 330, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::OM_FOLIO_SP, 215, 315, kMmToUm), |
| MAP_CLOUD_PRINT_MEDIA_SIZE(MediaSize::OM_INVITE, 220, 220, kMmToUm)}; |
| #undef MAP_CLOUD_PRINT_MEDIA_SIZE |
| |
| const gfx::Size& FindMediaSizeByType(MediaSize size_name) { |
| for (const auto& media : kMediaDefinitions) { |
| if (media.id == size_name) { |
| return media.size_um; |
| } |
| } |
| NOTREACHED(); |
| } |
| |
| const MediaDefinition* FindMediaBySize(const gfx::Size& size_um) { |
| const MediaDefinition* result = nullptr; |
| for (const auto& media : kMediaDefinitions) { |
| int32_t diff = |
| std::max(std::abs(size_um.width() - media.size_um.width()), |
| std::abs(size_um.height() - media.size_um.height())); |
| if (diff < kSizeThresholdUm) |
| result = &media; |
| } |
| return result; |
| } |
| |
| template <class T, class IdType> |
| std::string TypeToString(const T& names, IdType id) { |
| for (const auto& name : names) { |
| if (id == name.id) |
| return name.json_name; |
| } |
| NOTREACHED(); |
| } |
| |
| template <class T, class IdType> |
| bool TypeFromString(const T& names, const std::string& type, IdType* id) { |
| for (const auto& name : names) { |
| if (type == name.json_name) { |
| *id = name.id; |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| } // namespace |
| |
| PwgRasterConfig::PwgRasterConfig() |
| : document_sheet_back(DocumentSheetBack::ROTATED), |
| reverse_order_streaming(false), |
| rotate_all_pages(false) {} |
| |
| PwgRasterConfig::~PwgRasterConfig() = default; |
| |
| RangeVendorCapability::RangeVendorCapability() = default; |
| |
| RangeVendorCapability::RangeVendorCapability(ValueType value_type, |
| const std::string& min_value, |
| const std::string& max_value) |
| : RangeVendorCapability(value_type, |
| min_value, |
| max_value, |
| /*default_value=*/"") {} |
| |
| RangeVendorCapability::RangeVendorCapability(ValueType value_type, |
| const std::string& min_value, |
| const std::string& max_value, |
| const std::string& default_value) |
| : value_type_(value_type), |
| min_value_(min_value), |
| max_value_(max_value), |
| default_value_(default_value) {} |
| |
| RangeVendorCapability::RangeVendorCapability(RangeVendorCapability&& other) = |
| default; |
| |
| RangeVendorCapability::~RangeVendorCapability() = default; |
| |
| RangeVendorCapability& RangeVendorCapability::operator=( |
| RangeVendorCapability&& other) = default; |
| |
| bool RangeVendorCapability::IsValid() const { |
| if (min_value_.empty() || max_value_.empty()) |
| return false; |
| switch (value_type_) { |
| case ValueType::FLOAT: { |
| double min_value; |
| double max_value; |
| if (!base::StringToDouble(min_value_, &min_value) || |
| !base::StringToDouble(max_value_, &max_value) || |
| min_value > max_value) { |
| return false; |
| } |
| if (!default_value_.empty()) { |
| double default_value; |
| if (!base::StringToDouble(default_value_, &default_value) || |
| default_value < min_value || default_value > max_value) { |
| return false; |
| } |
| } |
| return true; |
| } |
| case ValueType::INTEGER: { |
| int min_value; |
| int max_value; |
| if (!base::StringToInt(min_value_, &min_value) || |
| !base::StringToInt(max_value_, &max_value) || min_value > max_value) { |
| return false; |
| } |
| if (!default_value_.empty()) { |
| int default_value; |
| if (!base::StringToInt(default_value_, &default_value) || |
| default_value < min_value || default_value > max_value) { |
| return false; |
| } |
| } |
| return true; |
| } |
| } |
| NOTREACHED() << "Bad range capability value type"; |
| } |
| |
| bool RangeVendorCapability::LoadFrom(const base::Value::Dict& dict) { |
| const std::string* value_type_str = dict.FindString(kKeyValueType); |
| if (!value_type_str || !TypeFromString(kRangeVendorCapabilityTypeNames, |
| *value_type_str, &value_type_)) { |
| return false; |
| } |
| const std::string* min_value_str = dict.FindString(kMinValue); |
| if (!min_value_str) |
| return false; |
| min_value_ = *min_value_str; |
| const std::string* max_value_str = dict.FindString(kMaxValue); |
| if (!max_value_str) |
| return false; |
| max_value_ = *max_value_str; |
| const std::string* default_value_str = dict.FindString(kDefaultValue); |
| if (default_value_str) |
| default_value_ = *default_value_str; |
| return IsValid(); |
| } |
| |
| void RangeVendorCapability::SaveTo(base::Value::Dict* dict) const { |
| DCHECK(IsValid()); |
| dict->Set(kKeyValueType, |
| TypeToString(kRangeVendorCapabilityTypeNames, value_type_)); |
| dict->Set(kMinValue, min_value_); |
| dict->Set(kMaxValue, max_value_); |
| if (!default_value_.empty()) |
| dict->Set(kDefaultValue, default_value_); |
| } |
| |
| SelectVendorCapabilityOption::SelectVendorCapabilityOption() = default; |
| |
| SelectVendorCapabilityOption::SelectVendorCapabilityOption( |
| const std::string& value, |
| const std::string& display_name) |
| : value(value), display_name(display_name) {} |
| |
| SelectVendorCapabilityOption::~SelectVendorCapabilityOption() = default; |
| |
| bool SelectVendorCapabilityOption::IsValid() const { |
| return !value.empty() && !display_name.empty(); |
| } |
| |
| TypedValueVendorCapability::TypedValueVendorCapability() = default; |
| |
| TypedValueVendorCapability::TypedValueVendorCapability(ValueType value_type) |
| : TypedValueVendorCapability(value_type, /*default_value=*/"") {} |
| |
| TypedValueVendorCapability::TypedValueVendorCapability( |
| ValueType value_type, |
| const std::string& default_value) |
| : value_type_(value_type), default_value_(default_value) {} |
| |
| TypedValueVendorCapability::TypedValueVendorCapability( |
| TypedValueVendorCapability&& other) = default; |
| |
| TypedValueVendorCapability::~TypedValueVendorCapability() = default; |
| |
| TypedValueVendorCapability& TypedValueVendorCapability::operator=( |
| TypedValueVendorCapability&& other) = default; |
| |
| bool TypedValueVendorCapability::IsValid() const { |
| if (default_value_.empty()) |
| return true; |
| switch (value_type_) { |
| case ValueType::BOOLEAN: |
| return default_value_ == "true" || default_value_ == "false"; |
| case ValueType::FLOAT: { |
| double value; |
| return base::StringToDouble(default_value_, &value); |
| } |
| case ValueType::INTEGER: { |
| int value; |
| return base::StringToInt(default_value_, &value); |
| } |
| case ValueType::STRING: |
| return true; |
| } |
| NOTREACHED() << "Bad typed value capability value type"; |
| } |
| |
| bool TypedValueVendorCapability::LoadFrom(const base::Value::Dict& dict) { |
| const std::string* value_type_str = dict.FindString(kKeyValueType); |
| if (!value_type_str || !TypeFromString(kTypedValueVendorCapabilityTypeNames, |
| *value_type_str, &value_type_)) { |
| return false; |
| } |
| const std::string* default_value_str = dict.FindString(kDefaultValue); |
| if (default_value_str) |
| default_value_ = *default_value_str; |
| return IsValid(); |
| } |
| |
| void TypedValueVendorCapability::SaveTo(base::Value::Dict* dict) const { |
| DCHECK(IsValid()); |
| dict->Set(kKeyValueType, |
| TypeToString(kTypedValueVendorCapabilityTypeNames, value_type_)); |
| if (!default_value_.empty()) |
| dict->Set(kDefaultValue, default_value_); |
| } |
| |
| VendorCapability::VendorCapability() : type_(Type::NONE) {} |
| |
| VendorCapability::VendorCapability(const std::string& id, |
| const std::string& display_name, |
| RangeVendorCapability range_capability) |
| : type_(Type::RANGE), |
| id_(id), |
| display_name_(display_name), |
| range_capability_(std::move(range_capability)) {} |
| |
| VendorCapability::VendorCapability(const std::string& id, |
| const std::string& display_name, |
| SelectVendorCapability select_capability) |
| : type_(Type::SELECT), |
| id_(id), |
| display_name_(display_name), |
| select_capability_(std::move(select_capability)) {} |
| |
| VendorCapability::VendorCapability( |
| const std::string& id, |
| const std::string& display_name, |
| TypedValueVendorCapability typed_value_capability) |
| : type_(Type::TYPED_VALUE), |
| id_(id), |
| display_name_(display_name), |
| typed_value_capability_(std::move(typed_value_capability)) {} |
| |
| VendorCapability::VendorCapability(VendorCapability&& other) |
| : type_(other.type_), id_(other.id_), display_name_(other.display_name_) { |
| switch (type_) { |
| case Type::NONE: |
| // No-op; |
| break; |
| case Type::RANGE: |
| new (&range_capability_) |
| RangeVendorCapability(std::move(other.range_capability_)); |
| break; |
| case Type::SELECT: |
| new (&select_capability_) |
| SelectVendorCapability(std::move(other.select_capability_)); |
| break; |
| case Type::TYPED_VALUE: |
| new (&typed_value_capability_) |
| TypedValueVendorCapability(std::move(other.typed_value_capability_)); |
| break; |
| default: |
| NOTREACHED(); |
| } |
| } |
| |
| VendorCapability::~VendorCapability() { |
| InternalCleanup(); |
| } |
| |
| void VendorCapability::InternalCleanup() { |
| switch (type_) { |
| case Type::NONE: |
| break; |
| case Type::RANGE: |
| range_capability_.~RangeVendorCapability(); |
| break; |
| case Type::SELECT: |
| select_capability_.~SelectVendorCapability(); |
| break; |
| case Type::TYPED_VALUE: |
| typed_value_capability_.~TypedValueVendorCapability(); |
| break; |
| default: |
| NOTREACHED(); |
| } |
| type_ = Type::NONE; |
| } |
| |
| bool VendorCapability::operator==(const VendorCapability& other) const { |
| if (type_ != other.type_ || id_ != other.id_ || |
| display_name_ != other.display_name_) { |
| return false; |
| } |
| switch (type_) { |
| case Type::NONE: |
| return true; |
| case Type::RANGE: |
| return range_capability_ == other.range_capability_; |
| case Type::SELECT: |
| return select_capability_ == other.select_capability_; |
| case Type::TYPED_VALUE: |
| return typed_value_capability_ == other.typed_value_capability_; |
| } |
| NOTREACHED() << "Bad vendor capability type"; |
| } |
| |
| bool VendorCapability::IsValid() const { |
| if (id_.empty() || display_name_.empty()) |
| return false; |
| switch (type_) { |
| case Type::NONE: |
| return false; |
| case Type::RANGE: |
| return range_capability_.IsValid(); |
| case Type::SELECT: |
| return select_capability_.IsValid(); |
| case Type::TYPED_VALUE: |
| return typed_value_capability_.IsValid(); |
| } |
| NOTREACHED() << "Bad vendor capability type"; |
| } |
| |
| bool VendorCapability::LoadFrom(const base::Value::Dict& dict) { |
| InternalCleanup(); |
| const std::string* type_str = dict.FindString(kKeyType); |
| Type type; |
| if (!type_str || |
| !TypeFromString(kVendorCapabilityTypeNames, *type_str, &type)) { |
| return false; |
| } |
| |
| const std::string* id_str = dict.FindString(kKeyId); |
| if (!id_str) |
| return false; |
| |
| id_ = *id_str; |
| const std::string* display_name_str = dict.FindString(kKeyDisplayName); |
| if (!display_name_str) |
| return false; |
| |
| display_name_ = *display_name_str; |
| const base::Value::Dict* range_capability_value = |
| dict.FindDict(kOptionRangeCapability); |
| if (!range_capability_value == (type == Type::RANGE)) |
| return false; |
| |
| const base::Value::Dict* select_capability_value = |
| dict.FindDict(kOptionSelectCapability); |
| if (!select_capability_value == (type == Type::SELECT)) |
| return false; |
| |
| const base::Value::Dict* typed_value_capability_value = |
| dict.FindDict(kOptionTypedValueCapability); |
| if (!typed_value_capability_value == (type == Type::TYPED_VALUE)) |
| return false; |
| |
| type_ = type; |
| switch (type_) { |
| case Type::NONE: |
| default: |
| NOTREACHED(); |
| case Type::RANGE: |
| new (&range_capability_) RangeVendorCapability(); |
| return range_capability_.LoadFrom(*range_capability_value); |
| case Type::SELECT: |
| new (&select_capability_) SelectVendorCapability(); |
| return select_capability_.LoadFrom(*select_capability_value); |
| case Type::TYPED_VALUE: |
| new (&typed_value_capability_) TypedValueVendorCapability(); |
| return typed_value_capability_.LoadFrom(*typed_value_capability_value); |
| } |
| } |
| |
| void VendorCapability::SaveTo(base::Value::Dict* dict) const { |
| DCHECK(IsValid()); |
| dict->Set(kKeyType, TypeToString(kVendorCapabilityTypeNames, type_)); |
| dict->Set(kKeyId, id_); |
| dict->Set(kKeyDisplayName, display_name_); |
| |
| switch (type_) { |
| case Type::NONE: |
| NOTREACHED(); |
| case Type::RANGE: { |
| base::Value::Dict range_capability_value; |
| range_capability_.SaveTo(&range_capability_value); |
| dict->Set(kOptionRangeCapability, std::move(range_capability_value)); |
| break; |
| } |
| case Type::SELECT: { |
| base::Value::Dict select_capability_value; |
| select_capability_.SaveTo(&select_capability_value); |
| dict->Set(kOptionSelectCapability, std::move(select_capability_value)); |
| break; |
| } |
| case Type::TYPED_VALUE: { |
| base::Value::Dict typed_value_capability_value; |
| typed_value_capability_.SaveTo(&typed_value_capability_value); |
| dict->Set(kOptionTypedValueCapability, |
| std::move(typed_value_capability_value)); |
| break; |
| } |
| } |
| } |
| |
| Color::Color() : type(ColorType::AUTO_COLOR) {} |
| |
| Color::Color(ColorType type) : type(type) { |
| } |
| |
| bool Color::IsValid() const { |
| if (type != ColorType::CUSTOM_COLOR && type != ColorType::CUSTOM_MONOCHROME) |
| return true; |
| return !vendor_id.empty() && !custom_display_name.empty(); |
| } |
| |
| VendorItem::VendorItem() = default; |
| |
| VendorItem::VendorItem(const std::string& id, const std::string& value) |
| : id(id), value(value) {} |
| |
| bool VendorItem::IsValid() const { |
| return !id.empty() && !value.empty(); |
| } |
| |
| Margins::Margins() : top_um(0), right_um(0), bottom_um(0), left_um(0) {} |
| |
| Margins::Margins(int32_t top_um, |
| int32_t right_um, |
| int32_t bottom_um, |
| int32_t left_um) |
| : top_um(top_um), |
| right_um(right_um), |
| bottom_um(bottom_um), |
| left_um(left_um) {} |
| |
| bool Margins::operator==(const Margins& other) const { |
| return top_um == other.top_um && right_um == other.right_um && |
| bottom_um == other.bottom_um; |
| } |
| |
| Dpi::Dpi() : horizontal(0), vertical(0) { |
| } |
| |
| Dpi::Dpi(int32_t horizontal, int32_t vertical) |
| : horizontal(horizontal), vertical(vertical) {} |
| |
| bool Dpi::IsValid() const { |
| return horizontal > 0 && vertical > 0; |
| } |
| |
| Media::Media() |
| : size_name(MediaSize::CUSTOM_MEDIA), |
| is_continuous_feed(false), |
| max_height_um(0), |
| has_borderless_variant(false) {} |
| |
| Media::Media(const Media& other) = default; |
| |
| Media& Media::operator=(const Media& other) = default; |
| |
| bool Media::IsValid() const { |
| if (size_um.width() <= 0 || size_um.height() <= 0) { |
| return false; |
| } |
| |
| if (is_continuous_feed) { |
| if (max_height_um <= size_um.height()) { |
| return false; |
| } |
| } |
| |
| if (!gfx::Rect(size_um).Contains(printable_area_um)) { |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool Media::operator==(const Media& other) const { |
| return size_name == other.size_name && size_um == other.size_um && |
| is_continuous_feed == other.is_continuous_feed && |
| printable_area_um == other.printable_area_um && |
| max_height_um == other.max_height_um; |
| } |
| |
| MediaBuilder::MediaBuilder() = default; |
| |
| MediaBuilder& MediaBuilder::WithStandardName(MediaSize size_name) { |
| size_name_ = size_name; |
| custom_display_name_.clear(); |
| vendor_id_.clear(); |
| return *this; |
| } |
| |
| MediaBuilder& MediaBuilder::WithCustomName( |
| const std::string& custom_display_name, |
| const std::string& vendor_id) { |
| size_name_ = MediaSize::CUSTOM_MEDIA; |
| custom_display_name_ = custom_display_name; |
| vendor_id_ = vendor_id; |
| return *this; |
| } |
| |
| MediaBuilder& MediaBuilder::WithSizeAndDefaultPrintableArea( |
| const gfx::Size& size_um) { |
| return WithSizeAndPrintableArea(size_um, gfx::Rect(size_um)); |
| } |
| |
| MediaBuilder& MediaBuilder::WithSizeAndPrintableArea( |
| const gfx::Size& size_um, |
| const gfx::Rect& printable_area_um) { |
| size_um_ = size_um; |
| printable_area_um_ = printable_area_um; |
| return *this; |
| } |
| |
| MediaBuilder& MediaBuilder::WithNameMaybeBasedOnSize( |
| const std::string& custom_display_name, |
| const std::string& vendor_id) { |
| WithCustomName(custom_display_name, vendor_id); |
| const MediaDefinition* media = FindMediaBySize(size_um_); |
| if (media) { |
| size_name_ = media->id; |
| } |
| return *this; |
| } |
| |
| MediaBuilder& MediaBuilder::WithSizeAndPrintableAreaBasedOnStandardName() { |
| return WithSizeAndDefaultPrintableArea(FindMediaSizeByType(size_name_)); |
| } |
| |
| MediaBuilder& MediaBuilder::WithMaxHeight(int max_height_um) { |
| max_height_um_ = max_height_um; |
| return *this; |
| } |
| |
| MediaBuilder& MediaBuilder::WithBorderlessVariant(bool has_borderless_variant) { |
| has_borderless_variant_ = has_borderless_variant; |
| return *this; |
| } |
| |
| Media MediaBuilder::Build() const { |
| Media result; |
| result.size_name = size_name_; |
| result.size_um = size_um_; |
| result.is_continuous_feed = IsContinuousFeed(); |
| result.custom_display_name = custom_display_name_; |
| result.vendor_id = vendor_id_; |
| result.printable_area_um = printable_area_um_; |
| result.max_height_um = max_height_um_; |
| result.has_borderless_variant = has_borderless_variant_; |
| return result; |
| } |
| |
| bool MediaBuilder::IsContinuousFeed() const { |
| return max_height_um_ > 0; |
| } |
| |
| Interval::Interval() : start(0), end(0) { |
| } |
| |
| Interval::Interval(int32_t start, int32_t end) : start(start), end(end) {} |
| |
| Interval::Interval(int32_t start) : start(start), end(kMaxPageNumber) {} |
| |
| MediaType::MediaType() = default; |
| |
| MediaType::MediaType(const std::string& vendor_id, |
| const std::string& custom_display_name) |
| : vendor_id(vendor_id), custom_display_name(custom_display_name) {} |
| |
| bool MediaType::IsValid() const { |
| return !vendor_id.empty(); |
| } |
| |
| template <const char* kName> |
| class ItemsTraits { |
| public: |
| static std::string GetCapabilityPath() { |
| return base::JoinString({kSectionPrinter, kName}, "."); |
| } |
| |
| static std::string GetTicketItemPath() { |
| return base::JoinString({kSectionPrint, kName}, "."); |
| } |
| }; |
| |
| class NoValueValidation { |
| public: |
| template <class Option> |
| static bool IsValid(const Option&) { |
| return true; |
| } |
| }; |
| |
| class ContentTypeTraits : public NoValueValidation, |
| public ItemsTraits<kOptionContentType> { |
| public: |
| static bool Load(const base::Value::Dict& dict, ContentType* option) { |
| const std::string* content_type = dict.FindString(kKeyContentType); |
| if (!content_type) |
| return false; |
| *option = *content_type; |
| return true; |
| } |
| |
| static void Save(ContentType option, base::Value::Dict* dict) { |
| dict->Set(kKeyContentType, option); |
| } |
| }; |
| |
| class PwgRasterConfigTraits : public NoValueValidation, |
| public ItemsTraits<kOptionPwgRasterConfig> { |
| public: |
| static bool Load(const base::Value::Dict& dict, PwgRasterConfig* option) { |
| PwgRasterConfig option_out; |
| const base::Value* document_sheet_back = |
| dict.Find(kPwgRasterDocumentSheetBack); |
| if (document_sheet_back) { |
| if (!document_sheet_back->is_string() || |
| !TypeFromString(kDocumentSheetBackNames, |
| document_sheet_back->GetString(), |
| &option_out.document_sheet_back)) { |
| return false; |
| } |
| } |
| |
| const base::Value* document_types_supported = |
| dict.Find(kPwgRasterDocumentTypeSupported); |
| if (document_types_supported) { |
| if (!document_types_supported->is_list()) |
| return false; |
| for (const auto& type_value : document_types_supported->GetList()) { |
| if (!type_value.is_string()) |
| return false; |
| |
| const std::string& type = type_value.GetString(); |
| if (type == kTypeDocumentSupportedTypeSRGB8) { |
| option_out.document_types_supported.push_back( |
| PwgDocumentTypeSupported::SRGB_8); |
| } else if (type == kTypeDocumentSupportedTypeSGRAY8) { |
| option_out.document_types_supported.push_back( |
| PwgDocumentTypeSupported::SGRAY_8); |
| } |
| } |
| } |
| |
| option_out.reverse_order_streaming = |
| dict.FindBool(kPwgRasterReverseOrderStreaming).value_or(false); |
| option_out.rotate_all_pages = |
| dict.FindBool(kPwgRasterRotateAllPages).value_or(false); |
| *option = option_out; |
| return true; |
| } |
| |
| static void Save(const PwgRasterConfig& option, base::Value::Dict* dict) { |
| dict->Set( |
| kPwgRasterDocumentSheetBack, |
| TypeToString(kDocumentSheetBackNames, option.document_sheet_back)); |
| |
| if (!option.document_types_supported.empty()) { |
| base::Value::List supported_list; |
| for (const auto& type : option.document_types_supported) { |
| switch (type) { |
| case PwgDocumentTypeSupported::SRGB_8: |
| supported_list.Append(kTypeDocumentSupportedTypeSRGB8); |
| break; |
| case PwgDocumentTypeSupported::SGRAY_8: |
| supported_list.Append(kTypeDocumentSupportedTypeSGRAY8); |
| break; |
| } |
| } |
| dict->Set(kPwgRasterDocumentTypeSupported, std::move(supported_list)); |
| } |
| |
| if (option.reverse_order_streaming) { |
| dict->Set(kPwgRasterReverseOrderStreaming, |
| option.reverse_order_streaming); |
| } |
| |
| if (option.rotate_all_pages) { |
| dict->Set(kPwgRasterRotateAllPages, option.rotate_all_pages); |
| } |
| } |
| }; |
| |
| class VendorCapabilityTraits : public ItemsTraits<kOptionVendorCapability> { |
| public: |
| static bool IsValid(const VendorCapability& option) { |
| return option.IsValid(); |
| } |
| |
| static bool Load(const base::Value::Dict& dict, VendorCapability* option) { |
| return option->LoadFrom(dict); |
| } |
| |
| static void Save(const VendorCapability& option, base::Value::Dict* dict) { |
| option.SaveTo(dict); |
| } |
| }; |
| |
| class SelectVendorCapabilityTraits |
| : public ItemsTraits<kOptionSelectCapability> { |
| public: |
| static bool IsValid(const SelectVendorCapabilityOption& option) { |
| return option.IsValid(); |
| } |
| |
| static bool Load(const base::Value::Dict& dict, |
| SelectVendorCapabilityOption* option) { |
| const std::string* value = dict.FindString(kKeyValue); |
| if (!value) |
| return false; |
| option->value = *value; |
| const std::string* display_name = dict.FindString(kKeyDisplayName); |
| if (!display_name) |
| return false; |
| option->display_name = *display_name; |
| return true; |
| } |
| |
| static void Save(const SelectVendorCapabilityOption& option, |
| base::Value::Dict* dict) { |
| dict->Set(kKeyValue, option.value); |
| dict->Set(kKeyDisplayName, option.display_name); |
| } |
| }; |
| |
| class ColorTraits : public ItemsTraits<kOptionColor> { |
| public: |
| static bool IsValid(const Color& option) { return option.IsValid(); } |
| |
| static bool Load(const base::Value::Dict& dict, Color* option) { |
| const std::string* type = dict.FindString(kKeyType); |
| if (!type || !TypeFromString(kColorNames, *type, &option->type)) |
| return false; |
| const std::string* vendor_id = dict.FindString(kKeyVendorId); |
| if (vendor_id) |
| option->vendor_id = *vendor_id; |
| const std::string* custom_display_name = |
| dict.FindString(kKeyCustomDisplayName); |
| if (custom_display_name) |
| option->custom_display_name = *custom_display_name; |
| return true; |
| } |
| |
| static void Save(const Color& option, base::Value::Dict* dict) { |
| dict->Set(kKeyType, TypeToString(kColorNames, option.type)); |
| if (!option.vendor_id.empty()) |
| dict->Set(kKeyVendorId, option.vendor_id); |
| if (!option.custom_display_name.empty()) { |
| dict->Set(kKeyCustomDisplayName, option.custom_display_name); |
| } |
| } |
| }; |
| |
| class DuplexTraits : public NoValueValidation, |
| public ItemsTraits<kOptionDuplex> { |
| public: |
| static bool Load(const base::Value::Dict& dict, DuplexType* option) { |
| const std::string* type = dict.FindString(kKeyType); |
| return type && TypeFromString(kDuplexNames, *type, option); |
| } |
| |
| static void Save(DuplexType option, base::Value::Dict* dict) { |
| dict->Set(kKeyType, TypeToString(kDuplexNames, option)); |
| } |
| }; |
| |
| class OrientationTraits : public NoValueValidation, |
| public ItemsTraits<kOptionPageOrientation> { |
| public: |
| static bool Load(const base::Value::Dict& dict, OrientationType* option) { |
| const std::string* type = dict.FindString(kKeyType); |
| return type && TypeFromString(kOrientationNames, *type, option); |
| } |
| |
| static void Save(OrientationType option, base::Value::Dict* dict) { |
| dict->Set(kKeyType, TypeToString(kOrientationNames, option)); |
| } |
| }; |
| |
| class CopiesTicketItemTraits : public NoValueValidation, |
| public ItemsTraits<kOptionCopies> { |
| public: |
| static bool Load(const base::Value::Dict& dict, int32_t* option) { |
| std::optional<int> copies = dict.FindInt(kOptionCopies); |
| if (!copies) |
| return false; |
| |
| *option = copies.value(); |
| return true; |
| } |
| |
| static void Save(int32_t option, base::Value::Dict* dict) { |
| dict->Set(kOptionCopies, option); |
| } |
| }; |
| |
| class CopiesCapabilityTraits : public NoValueValidation, |
| public ItemsTraits<kOptionCopies> { |
| public: |
| static bool Load(const base::Value::Dict& dict, Copies* option) { |
| std::optional<int> default_copies = dict.FindInt(kDefaultValue); |
| if (!default_copies) |
| return false; |
| |
| std::optional<int> max_copies = dict.FindInt(kMaxValue); |
| if (!max_copies) |
| return false; |
| |
| option->default_value = default_copies.value(); |
| option->max_value = max_copies.value(); |
| return true; |
| } |
| |
| static void Save(const Copies& option, base::Value::Dict* dict) { |
| dict->Set(kDefaultValue, option.default_value); |
| dict->Set(kMaxValue, option.max_value); |
| } |
| }; |
| |
| class MarginsTraits : public NoValueValidation, |
| public ItemsTraits<kOptionMargins> { |
| public: |
| static bool Load(const base::Value::Dict& dict, Margins* option) { |
| std::optional<int> top_um = dict.FindInt(kMarginTop); |
| std::optional<int> right_um = dict.FindInt(kMarginRight); |
| std::optional<int> bottom_um = dict.FindInt(kMarginBottom); |
| std::optional<int> left_um = dict.FindInt(kMarginLeft); |
| if (!top_um || !right_um || !bottom_um || !left_um) |
| return false; |
| option->top_um = top_um.value(); |
| option->right_um = right_um.value(); |
| option->bottom_um = bottom_um.value(); |
| option->left_um = left_um.value(); |
| return true; |
| } |
| |
| static void Save(const Margins& option, base::Value::Dict* dict) { |
| dict->Set(kMarginTop, option.top_um); |
| dict->Set(kMarginRight, option.right_um); |
| dict->Set(kMarginBottom, option.bottom_um); |
| dict->Set(kMarginLeft, option.left_um); |
| } |
| }; |
| |
| class DpiTraits : public ItemsTraits<kOptionDpi> { |
| public: |
| static bool IsValid(const Dpi& option) { return option.IsValid(); } |
| |
| static bool Load(const base::Value::Dict& dict, Dpi* option) { |
| std::optional<int> horizontal = dict.FindInt(kDpiHorizontal); |
| std::optional<int> vertical = dict.FindInt(kDpiVertical); |
| if (!horizontal || !vertical) |
| return false; |
| option->horizontal = horizontal.value(); |
| option->vertical = vertical.value(); |
| return true; |
| } |
| |
| static void Save(const Dpi& option, base::Value::Dict* dict) { |
| dict->Set(kDpiHorizontal, option.horizontal); |
| dict->Set(kDpiVertical, option.vertical); |
| } |
| }; |
| |
| class FitToPageTraits : public NoValueValidation, |
| public ItemsTraits<kOptionFitToPage> { |
| public: |
| static bool Load(const base::Value::Dict& dict, FitToPageType* option) { |
| const std::string* type = dict.FindString(kKeyType); |
| return type && TypeFromString(kFitToPageNames, *type, option); |
| } |
| |
| static void Save(FitToPageType option, base::Value::Dict* dict) { |
| dict->Set(kKeyType, TypeToString(kFitToPageNames, option)); |
| } |
| }; |
| |
| class PageRangeTraits : public ItemsTraits<kOptionPageRange> { |
| public: |
| static bool IsValid(const PageRange& option) { |
| for (const auto& item : option) { |
| if (item.start < 1 || item.end < 1) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| static bool Load(const base::Value::Dict& dict, PageRange* option) { |
| const base::Value::List* list_value = dict.FindList(kPageRangeInterval); |
| if (!list_value) |
| return false; |
| for (const base::Value& interval : *list_value) { |
| const auto& inverval_dict = interval.GetDict(); |
| int page_range_start = inverval_dict.FindInt(kPageRangeStart).value_or(1); |
| int page_range_end = |
| inverval_dict.FindInt(kPageRangeEnd).value_or(kMaxPageNumber); |
| option->push_back(Interval(page_range_start, page_range_end)); |
| } |
| return true; |
| } |
| |
| static void Save(const PageRange& option, base::Value::Dict* dict) { |
| if (!option.empty()) { |
| base::Value::List list; |
| for (const auto& item : option) { |
| base::Value::Dict interval; |
| interval.Set(kPageRangeStart, item.start); |
| if (item.end < kMaxPageNumber) |
| interval.Set(kPageRangeEnd, item.end); |
| list.Append(std::move(interval)); |
| } |
| dict->Set(kPageRangeInterval, std::move(list)); |
| } |
| } |
| }; |
| |
| class MediaTraits : public ItemsTraits<kOptionMediaSize> { |
| public: |
| static bool IsValid(const Media& option) { return option.IsValid(); } |
| |
| static bool Load(const base::Value::Dict& dict, Media* option) { |
| const std::string* type = dict.FindString(kKeyName); |
| if (type && !TypeFromString(kMediaDefinitions, *type, &option->size_name)) { |
| return false; |
| } |
| const std::string* custom_display_name = |
| dict.FindString(kKeyCustomDisplayName); |
| if (custom_display_name) |
| option->custom_display_name = *custom_display_name; |
| const std::string* vendor_id = dict.FindString(kKeyVendorId); |
| if (vendor_id) |
| option->vendor_id = *vendor_id; |
| std::optional<int> width_um = dict.FindInt(kMediaWidth); |
| if (width_um) { |
| option->size_um.set_width(width_um.value()); |
| } |
| std::optional<bool> is_continuous_feed = dict.FindBool(kMediaIsContinuous); |
| if (is_continuous_feed) { |
| option->is_continuous_feed = is_continuous_feed.value(); |
| } |
| if (is_continuous_feed.value_or(false)) { |
| // The min/max height is required for continuous feed media. |
| std::optional<int> min_height_um = dict.FindInt(kMediaMinHeight); |
| std::optional<int> max_height_um = dict.FindInt(kMediaMaxHeight); |
| if (!min_height_um || !max_height_um) { |
| return false; |
| } |
| // For variable height media, the min height is stored in the height |
| // attribute of the `size_um` parameter. |
| option->size_um.set_height(min_height_um.value()); |
| option->max_height_um = max_height_um.value(); |
| |
| // When `option` is a continuous feed, the printable area is not |
| // applicable. For consistency with the constructors, set the printable |
| // area to the default page size value. |
| option->printable_area_um = gfx::Rect(option->size_um); |
| return true; |
| } |
| std::optional<int> height_um = dict.FindInt(kMediaHeight); |
| if (height_um) { |
| option->size_um.set_height(height_um.value()); |
| } |
| std::optional<int> imageable_area_left = |
| dict.FindInt(kMediaImageableAreaLeft); |
| std::optional<int> imageable_area_bottom = |
| dict.FindInt(kMediaImageableAreaBottom); |
| std::optional<int> imageable_area_right = |
| dict.FindInt(kMediaImageableAreaRight); |
| std::optional<int> imageable_area_top = |
| dict.FindInt(kMediaImageableAreaTop); |
| if (imageable_area_left && imageable_area_bottom && imageable_area_right && |
| imageable_area_top) { |
| int width = imageable_area_right.value() - imageable_area_left.value(); |
| int height = imageable_area_top.value() - imageable_area_bottom.value(); |
| option->printable_area_um = |
| gfx::Rect(imageable_area_left.value(), imageable_area_bottom.value(), |
| width, height); |
| } |
| |
| std::optional<bool> has_borderless_variant = |
| dict.FindBool(kMediaHasBorderlessVariant); |
| if (has_borderless_variant) { |
| option->has_borderless_variant = has_borderless_variant.value(); |
| } |
| |
| return true; |
| } |
| |
| static void Save(const Media& option, base::Value::Dict* dict) { |
| if (option.size_name != MediaSize::CUSTOM_MEDIA) { |
| dict->Set(kKeyName, TypeToString(kMediaDefinitions, option.size_name)); |
| } |
| if (!option.custom_display_name.empty() || |
| option.size_name == MediaSize::CUSTOM_MEDIA) { |
| dict->Set(kKeyCustomDisplayName, option.custom_display_name); |
| } |
| if (!option.vendor_id.empty()) |
| dict->Set(kKeyVendorId, option.vendor_id); |
| if (option.size_um.width() > 0) |
| dict->Set(kMediaWidth, option.size_um.width()); |
| if (option.is_continuous_feed) { |
| // For variable height media, the height from `size_um` represents the min |
| // height, so it gets stored in `kMediaMinHeight`, not in `kMediaHeight`. |
| dict->Set(kMediaIsContinuous, true); |
| dict->Set(kMediaMinHeight, option.size_um.height()); |
| dict->Set(kMediaMaxHeight, option.max_height_um); |
| } else if (option.size_um.height() > 0) { |
| dict->Set(kMediaHeight, option.size_um.height()); |
| } |
| if (!option.is_continuous_feed && !option.printable_area_um.IsEmpty() && |
| gfx::Rect(option.size_um).Contains(option.printable_area_um)) { |
| dict->Set(kMediaImageableAreaLeft, option.printable_area_um.x()); |
| dict->Set(kMediaImageableAreaBottom, option.printable_area_um.y()); |
| dict->Set(kMediaImageableAreaRight, option.printable_area_um.x() + |
| option.printable_area_um.width()); |
| dict->Set(kMediaImageableAreaTop, option.printable_area_um.y() + |
| option.printable_area_um.height()); |
| } |
| if (option.has_borderless_variant) { |
| dict->Set(kMediaHasBorderlessVariant, true); |
| } |
| } |
| }; |
| |
| class MediaTypeTraits : public ItemsTraits<kOptionMediaType> { |
| public: |
| static bool IsValid(const MediaType& option) { return option.IsValid(); } |
| |
| static bool Load(const base::Value::Dict& dict, MediaType* option) { |
| const std::string* vendor_id = dict.FindString(kKeyVendorId); |
| if (!vendor_id) { |
| return false; |
| } |
| option->vendor_id = *vendor_id; |
| const std::string* custom_display_name = |
| dict.FindString(kKeyCustomDisplayName); |
| if (custom_display_name) { |
| option->custom_display_name = *custom_display_name; |
| } |
| return true; |
| } |
| |
| static void Save(const MediaType& option, base::Value::Dict* dict) { |
| dict->Set(kKeyVendorId, option.vendor_id); |
| if (!option.custom_display_name.empty()) { |
| dict->Set(kKeyCustomDisplayName, option.custom_display_name); |
| } |
| } |
| }; |
| |
| class CollateTraits : public NoValueValidation, |
| public ItemsTraits<kOptionCollate> { |
| public: |
| static const bool kDefault = true; |
| |
| static bool Load(const base::Value::Dict& dict, bool* option) { |
| std::optional<bool> collate = dict.FindBool(kOptionCollate); |
| if (!collate) |
| return false; |
| *option = collate.value(); |
| return true; |
| } |
| |
| static void Save(bool option, base::Value::Dict* dict) { |
| dict->Set(kOptionCollate, option); |
| } |
| }; |
| |
| class ReverseTraits : public NoValueValidation, |
| public ItemsTraits<kOptionReverse> { |
| public: |
| static const bool kDefault = false; |
| |
| static bool Load(const base::Value::Dict& dict, bool* option) { |
| std::optional<bool> reverse = dict.FindBool(kOptionReverse); |
| if (!reverse) |
| return false; |
| *option = reverse.value(); |
| return true; |
| } |
| |
| static void Save(bool option, base::Value::Dict* dict) { |
| dict->Set(kOptionReverse, option); |
| } |
| }; |
| |
| class VendorItemTraits : public ItemsTraits<kOptionVendorItem> { |
| public: |
| static bool IsValid(const VendorItem& option) { return option.IsValid(); } |
| |
| static bool Load(const base::Value::Dict& dict, VendorItem* option) { |
| const std::string* id = dict.FindString(kKeyId); |
| if (!id) { |
| return false; |
| } |
| const std::string* value = dict.FindString(kKeyValue); |
| if (!value) { |
| return false; |
| } |
| option->id = *id; |
| option->value = *value; |
| return true; |
| } |
| |
| static void Save(const VendorItem& option, base::Value::Dict* dict) { |
| dict->Set(kKeyId, option.id); |
| dict->Set(kKeyValue, option.value); |
| } |
| }; |
| |
| #if BUILDFLAG(IS_CHROMEOS) |
| class PinTraits : public NoValueValidation, public ItemsTraits<kOptionPin> { |
| public: |
| static bool Load(const base::Value::Dict& dict, bool* option) { |
| std::optional<bool> supported = dict.FindBool(kPinSupported); |
| if (!supported) |
| return false; |
| *option = supported.value(); |
| return true; |
| } |
| |
| static void Save(bool option, base::Value::Dict* dict) { |
| dict->Set(kPinSupported, option); |
| } |
| }; |
| #endif // BUILDFLAG(IS_CHROMEOS) |
| |
| } // namespace printer |
| |
| template class ListCapability<printer::ContentType, printer::ContentTypeTraits>; |
| template class ValueCapability<printer::PwgRasterConfig, |
| printer::PwgRasterConfigTraits>; |
| template class ListCapability<printer::VendorCapability, |
| printer::VendorCapabilityTraits>; |
| template class SelectionCapability<printer::SelectVendorCapabilityOption, |
| printer::SelectVendorCapabilityTraits>; |
| template class SelectionCapability<printer::Color, printer::ColorTraits>; |
| template class SelectionCapability<printer::DuplexType, printer::DuplexTraits>; |
| template class SelectionCapability<printer::OrientationType, |
| printer::OrientationTraits>; |
| template class SelectionCapability<printer::Margins, printer::MarginsTraits>; |
| template class SelectionCapability<printer::Dpi, printer::DpiTraits>; |
| template class SelectionCapability<printer::FitToPageType, |
| printer::FitToPageTraits>; |
| template class SelectionCapability<printer::Media, printer::MediaTraits>; |
| template class SelectionCapability<printer::MediaType, |
| printer::MediaTypeTraits>; |
| template class ValueCapability<printer::Copies, |
| printer::CopiesCapabilityTraits>; |
| template class EmptyCapability<printer::PageRangeTraits>; |
| template class BooleanCapability<printer::CollateTraits>; |
| template class BooleanCapability<printer::ReverseTraits>; |
| #if BUILDFLAG(IS_CHROMEOS) |
| template class ValueCapability<bool, printer::PinTraits>; |
| #endif // BUILDFLAG(IS_CHROMEOS) |
| |
| template class TicketItem<printer::PwgRasterConfig, |
| printer::PwgRasterConfigTraits>; |
| template class TicketItem<printer::Color, printer::ColorTraits>; |
| template class TicketItem<printer::DuplexType, printer::DuplexTraits>; |
| template class TicketItem<printer::OrientationType, printer::OrientationTraits>; |
| template class TicketItem<printer::Margins, printer::MarginsTraits>; |
| template class TicketItem<printer::Dpi, printer::DpiTraits>; |
| template class TicketItem<printer::FitToPageType, printer::FitToPageTraits>; |
| template class TicketItem<printer::Media, printer::MediaTraits>; |
| template class TicketItem<int32_t, printer::CopiesTicketItemTraits>; |
| template class TicketItem<printer::PageRange, printer::PageRangeTraits>; |
| template class TicketItem<bool, printer::CollateTraits>; |
| template class TicketItem<bool, printer::ReverseTraits>; |
| template class ListCapability<printer::VendorItem, printer::VendorItemTraits>; |
| template class ListTicketItem<printer::VendorItem, printer::VendorItemTraits>; |
| |
| } // namespace cloud_devices |