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