1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_vcl.hxx" 26 27 #include <string.h> 28 29 #include "psputil.hxx" 30 31 #include "tools/debug.hxx" 32 33 namespace psp { 34 35 /* 36 * string convenience routines 37 */ 38 39 sal_Int32 40 getHexValueOf (sal_Int32 nValue, sal_Char* pBuffer) 41 { 42 const static sal_Char pHex [0x10] = { 43 '0', '1', '2', '3', '4', '5', '6', '7', 44 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 45 46 pBuffer[0] = pHex [(nValue & 0xF0) >> 4]; 47 pBuffer[1] = pHex [(nValue & 0x0F) ]; 48 49 return 2; 50 } 51 52 sal_Int32 53 getAlignedHexValueOf (sal_Int32 nValue, sal_Char* pBuffer) 54 { 55 // get sign 56 sal_Bool bNegative = nValue < 0; 57 nValue = bNegative ? -nValue : nValue; 58 59 // get required buffer size, must be a multiple of two 60 sal_Int32 nPrecision; 61 if (nValue < 0x80) 62 nPrecision = 2; 63 else 64 if (nValue < 0x8000) 65 nPrecision = 4; 66 else 67 if (nValue < 0x800000) 68 nPrecision = 6; 69 else 70 nPrecision = 8; 71 72 // convert the int into its hex representation, write it into the buffer 73 sal_Int32 nRet = nPrecision; 74 while (nPrecision) 75 { 76 nPrecision -= getHexValueOf (nValue % 256, pBuffer + nPrecision - 2 ); 77 nValue /= 256; 78 } 79 80 // set sign bit 81 if (bNegative) 82 { 83 switch (pBuffer[0]) 84 { 85 case '0' : pBuffer[0] = '8'; break; 86 case '1' : pBuffer[0] = '9'; break; 87 case '2' : pBuffer[0] = 'A'; break; 88 case '3' : pBuffer[0] = 'B'; break; 89 case '4' : pBuffer[0] = 'C'; break; 90 case '5' : pBuffer[0] = 'D'; break; 91 case '6' : pBuffer[0] = 'E'; break; 92 case '7' : pBuffer[0] = 'F'; break; 93 default: DBG_ERROR("Already a signed value"); 94 } 95 } 96 97 // report precision 98 return nRet; 99 } 100 101 102 sal_Int32 103 getValueOf (sal_Int32 nValue, sal_Char* pBuffer) 104 { 105 sal_Int32 nChar = 0; 106 if (nValue < 0) 107 { 108 pBuffer [nChar++] = '-'; 109 nValue *= -1; 110 } 111 else 112 if (nValue == 0) 113 { 114 pBuffer [nChar++] = '0'; 115 return nChar; 116 } 117 118 sal_Char pInvBuffer [32]; 119 sal_Int32 nInvChar = 0; 120 while (nValue > 0) 121 { 122 pInvBuffer [nInvChar++] = '0' + nValue % 10; 123 nValue /= 10; 124 } 125 while (nInvChar > 0) 126 { 127 pBuffer [nChar++] = pInvBuffer [--nInvChar]; 128 } 129 130 return nChar; 131 } 132 133 sal_Int32 134 appendStr (const sal_Char* pSrc, sal_Char* pDst) 135 { 136 sal_Int32 nBytes = strlen (pSrc); 137 strncpy (pDst, pSrc, nBytes + 1); 138 139 return nBytes; 140 } 141 142 sal_Int32 143 appendStr (const sal_Char* pSrc, sal_Char* pDst, sal_Int32 nBytes) 144 { 145 strncpy (pDst, pSrc, nBytes); 146 pDst [nBytes] = '\0'; 147 return nBytes; 148 } 149 150 /* 151 * copy strings to file 152 */ 153 154 sal_Bool 155 WritePS (osl::File* pFile, const sal_Char* pString) 156 { 157 sal_uInt64 nInLength = rtl_str_getLength (pString); 158 sal_uInt64 nOutLength = 0; 159 160 if (nInLength > 0 && pFile) 161 pFile->write (pString, nInLength, nOutLength); 162 163 return nInLength == nOutLength; 164 } 165 166 sal_Bool 167 WritePS (osl::File* pFile, const sal_Char* pString, sal_uInt64 nInLength) 168 { 169 sal_uInt64 nOutLength = 0; 170 171 if (nInLength > 0 && pFile) 172 pFile->write (pString, nInLength, nOutLength); 173 174 return nInLength == nOutLength; 175 } 176 177 sal_Bool 178 WritePS (osl::File* pFile, const rtl::OString &rString) 179 { 180 sal_uInt64 nInLength = rString.getLength(); 181 sal_uInt64 nOutLength = 0; 182 183 if (nInLength > 0 && pFile) 184 pFile->write (rString, nInLength, nOutLength); 185 186 return nInLength == nOutLength; 187 } 188 189 sal_Bool 190 WritePS (osl::File* pFile, const rtl::OUString &rString) 191 { 192 return WritePS (pFile, rtl::OUStringToOString(rString, RTL_TEXTENCODING_ASCII_US)); 193 } 194 195 /* 196 * cache converter for use in postscript drawing routines 197 */ 198 199 ConverterFactory::ConverterFactory() 200 { 201 } 202 203 ConverterFactory::~ConverterFactory () 204 { 205 for( std::map< rtl_TextEncoding, rtl_UnicodeToTextConverter >::const_iterator it = m_aConverters.begin(); it != m_aConverters.end(); ++it ) 206 rtl_destroyUnicodeToTextConverter (it->second); 207 } 208 209 rtl_UnicodeToTextConverter 210 ConverterFactory::Get (rtl_TextEncoding nEncoding) 211 { 212 if (rtl_isOctetTextEncoding( nEncoding )) 213 { 214 std::map< rtl_TextEncoding, rtl_UnicodeToTextConverter >::const_iterator it = 215 m_aConverters.find( nEncoding ); 216 rtl_UnicodeToTextConverter aConverter; 217 if (it == m_aConverters.end()) 218 { 219 aConverter = rtl_createUnicodeToTextConverter (nEncoding); 220 m_aConverters[nEncoding] = aConverter; 221 } 222 else 223 aConverter = it->second; 224 return aConverter; 225 } 226 return NULL; 227 } 228 229 // wrapper for rtl_convertUnicodeToText that handles the usual cases for 230 // textconversion in drawtext 231 sal_Size 232 ConverterFactory::Convert (const sal_Unicode *pText, int nTextLen, 233 sal_uChar *pBuffer, sal_Size nBufferSize, rtl_TextEncoding nEncoding) 234 { 235 const sal_uInt32 nCvtFlags = RTL_UNICODETOTEXT_FLAGS_UNDEFINED_QUESTIONMARK 236 | RTL_UNICODETOTEXT_FLAGS_INVALID_QUESTIONMARK ; 237 sal_uInt32 nCvtInfo; 238 sal_Size nCvtChars; 239 240 rtl_UnicodeToTextConverter aConverter = Get (nEncoding); 241 rtl_UnicodeToTextContext aContext = rtl_createUnicodeToTextContext (aConverter); 242 243 sal_Size nSize = rtl_convertUnicodeToText (aConverter, aContext, 244 pText, nTextLen, (sal_Char*)pBuffer, nBufferSize, 245 nCvtFlags, &nCvtInfo, &nCvtChars); 246 247 rtl_destroyUnicodeToTextContext (aConverter, aContext); 248 249 return nSize; 250 } 251 252 ConverterFactory* 253 GetConverterFactory () 254 { 255 static ConverterFactory* pCvt = NULL; 256 257 if (pCvt == NULL) 258 pCvt = new ConverterFactory; 259 260 return pCvt; 261 } 262 263 264 } /* namespace psp */ 265