1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 #ifndef INCLUDED_VCL_PPDPARSER_HXX 20 #define INCLUDED_VCL_PPDPARSER_HXX 21 22 #include <sal/config.h> 23 24 #include <cstddef> 25 #include <memory> 26 #include <string_view> 27 #include <unordered_map> 28 #include <vector> 29 30 #include <rtl/string.hxx> 31 #include <rtl/ustring.hxx> 32 #include <tools/solar.h> 33 #include <vcl/dllapi.h> 34 35 #define PRINTER_PPDDIR "driver" 36 37 namespace psp { 38 39 class PPDCache; 40 class PPDTranslator; 41 42 enum PPDValueType { eInvocation, eQuoted, eSymbol, eString, eNo }; 43 44 struct VCL_DLLPUBLIC PPDValue 45 { 46 PPDValueType m_eType; 47 //CustomOption stuff for fdo#43049 48 //see http://www.cups.org/documentation.php/spec-ppd.html#OPTIONS 49 //for full specs, only the basics are implemented here 50 bool m_bCustomOption; 51 mutable OUString m_aCustomOption; 52 OUString m_aOption; 53 OUString m_aValue; 54 }; 55 56 57 /* 58 * PPDKey - a container for the available options (=values) of a PPD keyword 59 */ 60 61 class PPDKey 62 { 63 friend class PPDParser; 64 friend class CPDManager; 65 66 typedef std::unordered_map< OUString, PPDValue > hash_type; 67 typedef std::vector< PPDValue* > value_type; 68 69 OUString m_aKey; 70 hash_type m_aValues; 71 value_type m_aOrderedValues; 72 const PPDValue* m_pDefaultValue; 73 bool m_bQueryValue; 74 OUString m_aGroup; 75 76 public: 77 enum class SetupType { ExitServer, Prolog, DocumentSetup, PageSetup, JCLSetup, AnySetup }; 78 private: 79 80 bool m_bUIOption; 81 int m_nOrderDependency; 82 SetupType m_eSetupType; 83 84 void eraseValue( const OUString& rOption ); 85 public: 86 PPDKey( const OUString& rKey ); 87 ~PPDKey(); 88 89 PPDValue* insertValue(const OUString& rOption, PPDValueType eType, bool bCustomOption = false); countValues() const90 int countValues() const 91 { return m_aValues.size(); } 92 // neither getValue will return the query option 93 const PPDValue* getValue( int n ) const; 94 const PPDValue* getValue( const OUString& rOption ) const; 95 const PPDValue* getValueCaseInsensitive( const OUString& rOption ) const; getDefaultValue() const96 const PPDValue* getDefaultValue() const { return m_pDefaultValue; } getGroup() const97 const OUString& getGroup() const { return m_aGroup; } 98 getKey() const99 const OUString& getKey() const { return m_aKey; } isUIKey() const100 bool isUIKey() const { return m_bUIOption; } getSetupType() const101 SetupType getSetupType() const { return m_eSetupType; } getOrderDependency() const102 int getOrderDependency() const { return m_nOrderDependency; } 103 }; 104 105 // define a hash for PPDKey 106 struct PPDKeyhash 107 { operator ()psp::PPDKeyhash108 size_t operator()( const PPDKey * pKey) const 109 { return reinterpret_cast<size_t>(pKey); } 110 }; 111 112 113 /* 114 * PPDParser - parses a PPD file and contains all available keys from it 115 */ 116 117 class PPDParser 118 { 119 friend class PPDContext; 120 friend class CUPSManager; 121 friend class CPDManager; 122 friend class PPDCache; 123 124 typedef std::unordered_map< OUString, std::unique_ptr<PPDKey> > hash_type; 125 typedef std::vector< PPDKey* > value_type; 126 127 void insertKey( std::unique_ptr<PPDKey> pKey ); 128 public: 129 struct PPDConstraint 130 { 131 const PPDKey* m_pKey1; 132 const PPDValue* m_pOption1; 133 const PPDKey* m_pKey2; 134 const PPDValue* m_pOption2; 135 PPDConstraintpsp::PPDParser::PPDConstraint136 PPDConstraint() : m_pKey1( nullptr ), m_pOption1( nullptr ), m_pKey2( nullptr ), m_pOption2( nullptr ) {} 137 }; 138 private: 139 hash_type m_aKeys; 140 value_type m_aOrderedKeys; 141 ::std::vector< PPDConstraint > m_aConstraints; 142 143 // the full path of the PPD file 144 OUString m_aFile; 145 // some basic attributes 146 bool m_bColorDevice; 147 bool m_bType42Capable; 148 sal_uLong m_nLanguageLevel; 149 rtl_TextEncoding m_aFileEncoding; 150 151 152 // shortcuts to important keys and their default values 153 // imageable area 154 const PPDKey* m_pImageableAreas; 155 // paper dimensions 156 const PPDValue* m_pDefaultPaperDimension; 157 const PPDKey* m_pPaperDimensions; 158 // paper trays 159 const PPDValue* m_pDefaultInputSlot; 160 // resolutions 161 const PPDValue* m_pDefaultResolution; 162 163 // translations 164 std::unique_ptr<PPDTranslator> m_pTranslator; 165 166 PPDParser( const OUString& rFile ); 167 PPDParser(const OUString& rFile, const std::vector<PPDKey*>& keys); 168 169 void parseOrderDependency(const OString& rLine); 170 void parseOpenUI(const OString& rLine, std::string_view rPPDGroup); 171 void parseConstraint(const OString& rLine); 172 void parse( std::vector< OString >& rLines ); 173 174 OUString handleTranslation(const OString& i_rString, bool i_bIsGlobalized); 175 176 static void scanPPDDir( const OUString& rDir ); 177 static void initPPDFiles(PPDCache &rPPDCache); 178 static OUString getPPDFile( const OUString& rFile ); 179 public: 180 ~PPDParser(); 181 static const PPDParser* getParser( const OUString& rFile ); 182 183 const PPDKey* getKey( int n ) const; 184 const PPDKey* getKey( const OUString& rKey ) const; getKeys() const185 int getKeys() const { return m_aKeys.size(); } 186 bool hasKey( const PPDKey* ) const; 187 getConstraints() const188 const ::std::vector< PPDConstraint >& getConstraints() const { return m_aConstraints; } 189 isColorDevice() const190 bool isColorDevice() const { return m_bColorDevice; } isType42Capable() const191 bool isType42Capable() const { return m_bType42Capable; } getLanguageLevel() const192 sal_uLong getLanguageLevel() const { return m_nLanguageLevel; } 193 194 OUString getDefaultPaperDimension() const; getDefaultPaperDimension(int & rWidth,int & rHeight) const195 void getDefaultPaperDimension( int& rWidth, int& rHeight ) const 196 { getPaperDimension( getDefaultPaperDimension(), rWidth, rHeight ); } 197 bool getPaperDimension( std::u16string_view rPaperName, 198 int& rWidth, int& rHeight ) const; 199 // width and height in pt 200 // returns false if paper not found 201 202 // match the best paper for width and height 203 OUString matchPaper( int nWidth, int nHeight ) const; 204 205 bool getMargins( std::u16string_view rPaperName, 206 int &rLeft, int& rRight, 207 int &rUpper, int& rLower ) const; 208 // values in pt 209 // returns true if paper found 210 211 // values int pt 212 213 OUString getDefaultInputSlot() const; 214 215 void getDefaultResolution( int& rXRes, int& rYRes ) const; 216 // values in dpi 217 static void getResolutionFromString( const OUString&, int&, int& ); 218 // helper function 219 220 OUString translateKey( const OUString& i_rKey ) const; 221 OUString translateOption( const OUString& i_rKey, 222 const OUString& i_rOption ) const; 223 }; 224 225 226 /* 227 * PPDContext - a class to manage user definable states based on the 228 * contents of a PPDParser. 229 */ 230 231 class PPDContext 232 { 233 typedef std::unordered_map< const PPDKey*, const PPDValue*, PPDKeyhash > hash_type; 234 hash_type m_aCurrentValues; 235 const PPDParser* m_pParser; 236 237 // returns false: check failed, new value is constrained 238 // true: check succeeded, new value can be set 239 bool checkConstraints( const PPDKey*, const PPDValue*, bool bDoReset ); 240 bool resetValue( const PPDKey*, bool bDefaultable = false ); 241 public: 242 PPDContext(); PPDContext(const PPDContext & rContext)243 PPDContext( const PPDContext& rContext ) { operator=( rContext ); } 244 PPDContext& operator=( const PPDContext& rContext ) = default; 245 PPDContext& operator=( PPDContext&& rContext ); 246 247 void setParser( const PPDParser* ); getParser() const248 const PPDParser* getParser() const { return m_pParser; } 249 250 const PPDValue* getValue( const PPDKey* ) const; 251 const PPDValue* setValue( const PPDKey*, const PPDValue*, bool bDontCareForConstraints = false ); 252 countValuesModified() const253 std::size_t countValuesModified() const { return m_aCurrentValues.size(); } 254 const PPDKey* getModifiedKey( std::size_t n ) const; 255 256 // public wrapper for the private method 257 bool checkConstraints( const PPDKey*, const PPDValue* ); 258 259 // for printer setup 260 char* getStreamableBuffer( sal_uLong& rBytes ) const; 261 void rebuildFromStreamBuffer(const std::vector<char> &rBuffer); 262 263 // convenience 264 int getRenderResolution() const; 265 266 // width, height in points, paper will contain the name of the selected 267 // paper after the call 268 void getPageSize( OUString& rPaper, int& rWidth, int& rHeight ) const; 269 }; 270 271 } // namespace 272 273 #endif // INCLUDED_VCL_PPDPARSER_HXX 274 275 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 276