// $Id: htmlfltr.cpp 1282 2006-06-09 09:46:49Z alex $ /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE ================================XARAHEADERSTART=========================== Xara LX, a vector drawing and manipulation program. Copyright (C) 1993-2006 Xara Group Ltd. Copyright on certain contributions may be held in joint with their respective authors. See AUTHORS file for details. LICENSE TO USE AND MODIFY SOFTWARE ---------------------------------- This file is part of Xara LX. Xara LX is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Xara LX and its component source files are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Xara LX (see the file GPL in the root directory of the distribution); if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ADDITIONAL RIGHTS ----------------- Conditional upon your continuing compliance with the GNU General Public License described above, Xara Group Ltd grants to you certain additional rights. The additional rights are to use, modify, and distribute the software together with the wxWidgets library, the wxXtra library, and the "CDraw" library and any other such library that any version of Xara LX relased by Xara Group Ltd requires in order to compile and execute, including the static linking of that library to XaraLX. In the case of the "CDraw" library, you may satisfy obligation under the GNU General Public License to provide source code by providing a binary copy of the library concerned and a copy of the license accompanying it. Nothing in this section restricts any of the rights you have under the GNU General Public License. SCOPE OF LICENSE ---------------- This license applies to this program (XaraLX) and its constituent source files only, and does not necessarily apply to other Xara products which may in part share the same code base, and are subject to their own licensing terms. This license does not apply to files in the wxXtra directory, which are built into a separate library, and are subject to the wxWindows license contained within that directory in the file "WXXTRA-LICENSE". This license does not apply to the binary libraries (if any) within the "libs" directory, which are subject to a separate license contained within that directory in the file "LIBS-LICENSE". ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS ---------------------------------------------- Subject to the terms of the GNU Public License (see above), you are free to do whatever you like with your modifications. However, you may (at your option) wish contribute them to Xara's source tree. You can find details of how to do this at: http://www.xaraxtreme.org/developers/ Prior to contributing your modifications, you will need to complete our contributor agreement. This can be found at: http://www.xaraxtreme.org/developers/contribute/ Please note that Xara will not accept modifications which modify any of the text between the start and end of this header (marked XARAHEADERSTART and XARAHEADEREND). MARKS ----- Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara designs are registered or unregistered trademarks, design-marks, and/or service marks of Xara Group Ltd. All rights in these marks are reserved. Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. http://www.xara.com/ =================================XARAHEADEREND============================ */ #include "camtypes.h" //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "filtrres.h" //#include "oilfltrs.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "htmlfltr.h" #include "htmllist.h" #include "backgrnd.h" //#include "htmldwnd.h" #include "fileutil.h" //#include "fixmem.h" // CCMalloc, CCFree - in camtypes.h [AUTOMATICALLY REMOVED] //#include "spread.h" // See FindFirstImportPosition below - in camtypes.h [AUTOMATICALLY REMOVED] #include "cutop.h" // To get the duplication distance #include "webaddr.h" // class WebAddress //#include "docview.h" //For DocView::FindTopLeftImportPosition - in camtypes.h [AUTOMATICALLY REMOVED] //#include "resimmap.h" //For some resources DECLARE_SOURCE("$Revision: 1282 $"); CC_IMPLEMENT_DYNAMIC(HTMLFilter, BaseTextFilter) #define new CAM_DEBUG_NEW //#define MAXTAGLENGTH 255 #define MAXTAGLENGTH 10240 // 10Ko // HTML tags #define HTMLTAG_UNKNOWN -1 // unknown tag #define HTMLTAG_UNUSED 0 // known tags but unused during parsing #define HTMLTAG_IMGSRC 1 #define HTMLTAG_BODY 2 #define HTMLTAG_BODYEND 3 #define HTMLTAG_LINK 4 #define HTMLTAG_LINKEND 5 #define HTMLTAG_INPUT 6 #define HTMLTAG_SELECT 7 #define HTMLTAG_HTML 8 #define HTMLTAG_HTMLEND 9 #define HTMLTAG_TITLE 10 #define HTMLTAG_TITLEEND 11 #define HTMLTAG_HEAD 12 #define HTMLTAG_HEADEND 13 #define HTMLTAG_CENTER 14 #define HTMLTAG_CENTEREND 15 #define HTMLTAG_EMBED 16 ////// add more TAGS here ////// // how many tags ? #define HTMLNUM_TAGS 16 BOOL HTMLFilter::ImportingHTML = FALSE; // list of all tags static struct { TCHAR *tag; HTMLTAG_TYPE Id; } HTML_Table[] = { {_T("img"), HTMLTAG_IMGSRC}, {_T("body"), HTMLTAG_BODY}, {_T("input"), HTMLTAG_INPUT}, {_T("center"), HTMLTAG_CENTER}, {_T("/center"),HTMLTAG_CENTEREND}, {_T("embed"), HTMLTAG_EMBED}, // The following tags are not used during the parsing, // but are used during HowCompatible() {_T("a href"), HTMLTAG_UNUSED}, {_T("select"), HTMLTAG_UNUSED}, {_T("/body"), HTMLTAG_UNUSED}, {_T("/a"), HTMLTAG_UNUSED}, {_T("html"), HTMLTAG_UNUSED}, {_T("/html"), HTMLTAG_UNUSED}, {_T("title"), HTMLTAG_UNUSED}, {_T("/title"), HTMLTAG_UNUSED}, {_T("head"), HTMLTAG_UNUSED}, {_T("/head"), HTMLTAG_UNUSED}, ////// add more TAGS here ////// ///// just add the FIRST element of the HTML tag /////// ///// see doc about the parser for more details ///// }; // Lookup for a token in the list of known HTML tags static INT32 FindTagId(const TCHAR* Token) { //Changed by Graham 29/5/97 so the comparison is case insensitive for (INT32 i=0;i HTMLFilter::HTMLFilter() Author: Olivier_Gascoin (Xara Group Ltd) Created: 26/03/97 Purpose: Constructor. Initialises member variables and load ressources ********************************************************************************************/ HTMLFilter::HTMLFilter() { // Set up filter descriptions. FilterName.Load(_R(IDS_FILTERNAME_HTML)); FilterInfo.Load(_R(IDS_FILTERINFO_HTML)); FilterID = FILTERID_HTML; #ifndef STANDALONE Flags.CanImport = TRUE; Flags.CanExport = FALSE; #else Flags.CanImport = FALSE; Flags.CanExport = FALSE; #endif m_WarningsString.Empty(); } /******************************************************************************************** > HTMLFilter::~HTMLFilter() Author: Olivier_Gascoin (Xara Group Ltd) Created: 26/03/97 Purpose: Destructor. Frees memory and cleans up. ********************************************************************************************/ HTMLFilter::~HTMLFilter() { //DeInit1(); } /******************************************************************************************** > INT32 HTMLFilter::Init() Author: Olivier_Gascoin (Xara Group Ltd) Created: 26/03/97 Returns: TRUE if init ok Purpose: Initialisation of the filter ********************************************************************************************/ INT32 HTMLFilter::Init() { // allocate memory for member variables //if (!Init1()) // return FALSE; // Get the OILFilter object pOILFilter = new HTMLOILFilter(this); if (pOILFilter == NULL) return FALSE; // init the Bitmap download operation if(!OpBitmapDownload::Init()) return FALSE; // All ok return TRUE; } /******************************************************************************************** > BOOL HTMLFilter::PreHowCompatible() Author: Olivier_Gascoin (Xara Group Ltd) Created: 26/03/97 Returns: True if it it worked ok. Purpose: Allows a filter or set of filters to take some action or set up variables before being called by HowCompatible. A group of filters which share common code may require some variable set up before being asked to check the type. Base class does nothing and so works for all filters which do not require it. SeeAlso: HowCompatible ********************************************************************************************/ BOOL HTMLFilter::PreHowCompatible() { return TRUE; } /******************************************************************************************** > INT32 HTMLFilter::HowCompatible(PathName& Filename, ADDR HeaderStart, UINT32 HeaderSize,UINT32 FileSize) Author: Olivier_Gascoin (Xara Group Ltd) Created: 27/03/97 Returns: a value <= 10 depending on how we like the file. 10 mean it's HTML, 0 is definetely not HTML. Purpose: check whether the file is HTML or not I've considered that the file is HTML as soon as there is one HTML tags. SeeAlso: ********************************************************************************************/ INT32 HTMLFilter::HowCompatible(PathName& Filename, ADDR HeaderStart, UINT32 HeaderSize,UINT32 FileSize) { PORTNOTE("byteorder", "TODO: Check byte ordering") if (FileSize == 0 || pOILFilter == NULL) return 0; INT32 IsCompatible = 0; INT32 MaxCompatible = 0; // If this file doesn't have the right extension, then claim with a value lower than 10. // If we don't check the extension, this function will return 10 if it finds any HTML tag ID // within the buffer, even if the string is not contained within "<>" // // The header could be the text part on an EPS file (e.g. v1.1 native file format), so without // the extension match, this filter may try and import it, instead of leaving it to the EPS filter. // // Really, this function should be vamped up so that it spots real HTML tags, rather than just the tag ID // string. (Markn & Neville 7/8/97) // Reduced the 6 to 4 as most EPS filters return 5 if the %!Adobe is at the start of the file // Neville 27/10/97 if (pOILFilter->DoesExtensionOfPathNameMatch(&Filename)) MaxCompatible = 10; else MaxCompatible = 4; // Convert to lower case // CAN NOT do this on the main buffer as this would screw up all filters in the // chain below us. So take a copy of the buffer and then lower case that char * CopyFilterBuf = (char *) CCMalloc(HeaderSize); if (CopyFilterBuf == NULL) return 0; // Take a copy of the buffer memcpy(CopyFilterBuf, HeaderStart, HeaderSize); // and now finally, lower case it CopyFilterBuf = _strlwr(CopyFilterBuf); // all known HTML tags for (INT32 i=0;i BOOL HTMLFilter::DoImport(SelOperation *Op, CCLexFile* pFile, Document *DestDoc, BOOL AutoChosen = FALSE, ImportPosition *Pos = NULL, String_256* URL) Author: Olivier_Gascoin (Xara Group Ltd) Created: 26/03/97 Inputs: Op - pointer to the operation that this input process is associated with. pFile - The file that we should load DestDoc - URL - URL of the original imported file Returns: TRUE if the input operation worked ok, FALSE if not. Purpose: Errors: Fails (returns FALSE) if the document structure is incorrect, or if there is a problem with the bitmap. ********************************************************************************************/ BOOL HTMLFilter::DoImport(SelOperation *Op, CCLexFile* pFile, Document *DestDoc, BOOL AutoChosen, ImportPosition *Pos, KernelBitmap** ppImportedBitmap, DocCoord* pPosTranslate, String_256* URL) { ERROR2IF(Op == NULL, FALSE, "HTMLFilter::DoImportNULL operation supplied"); ERROR2IF(DestDoc == NULL, FALSE, "HTMLFilter::DoImportNULL document supplied"); // Blank our warnings string m_WarningsString.Empty(); HTMLFileList* HTMLList = new HTMLFileList; // Parse the file and add bitmap names in the list BOOL ok = ParseHTMLFile(pFile, HTMLList); //Now let's get the path to the file we are importing PathName pthImport=pFile->GetPathName(); if (URL == NULL) { String_256 URLTemp = ""; // import each bitmap ok = ScanListAndImport(HTMLList, &URLTemp, DestDoc, Op, pthImport); } else ok = ScanListAndImport(HTMLList, URL, DestDoc, Op, pthImport); // empty the list if ( HTMLList->GetCount()) HTMLList->DeleteAll(); delete HTMLList; // Now check the warning about problem data string // If it has anything in then warn the user about the problem if (ok && !m_WarningsString.IsEmpty()) { Error::SetError(0, m_WarningsString, 0); InformWarning(); } // All ok return ok; } /******************************************************************************************** > BOOL HTMLFilter::ScanListAndImport(HTMLFileList* HTMLList, String_256 &Address, Document *DestDoc, PathName pthImportFile) Author: Olivier_Gascoin (Xara Group Ltd) Created: 30/04/97 Inputs: HTMLList - the list of bitmap Address - the original URL DestDoc - pthImportFile - the path name of the HTML file that's being imported Returns: TRUE Purpose: scan the list and call DoImportBitmap() ********************************************************************************************/ BOOL HTMLFilter::ScanListAndImport(HTMLFileList* HTMLList, String_256* URL, Document *DestDoc, SelOperation *Op, PathName pthImportFile) { ERROR2IF(DestDoc == NULL, FALSE, "HTMLFilter::ScanListAndImport NULL document supplied"); ERROR2IF(HTMLList == NULL, FALSE, "HTMLFilter::ScanListAndImport NULL list supplied"); ERROR2IF(URL == NULL, FALSE, "HTMLFilter::ScanListAndImport NULL URL supplied"); // make sure there is at least one file in the list INT32 FileNumber = HTMLList->GetCount(); //If there were no files in the list, tell the user ERROR1IF(FileNumber==0, TRUE, _R(IDE_HTMLIMPORT_NOIMAGESINFILE)); // current file INT32 FileNum = 0; //Get the first position at which to import a bitmap DocCoord PosTranslate=GetImportPosition(DestDoc, FileNum); // first, get a pointer to the first element HTMLFileListItem* ListBitmaps = (HTMLFileListItem*)HTMLList->GetHead(); String_256 NewName; // scan the list while(ListBitmaps != NULL) { // get the Tag ID associated with the bitmap HTMLTAG_TYPE TagId = ListBitmaps->GetTagId(); //Get the name of the bitmap NewName= ListBitmaps->GetFileName(); // if only it's a web address then I call the bitmap download operation if (WebAddress::IsHTTP(*URL) || WebAddress::IsHTTP(ListBitmaps->GetFileName())) { // create the webaddress according base and relative URL WebAddress WebFileName(ListBitmaps->GetFileName()); WebFileName.Combine(*URL); // combine the existing URL with the filename // reconstitute the web address String_256 WebPath = WebFileName.GetWebAddress(); // call the bitmap download op //Graham 30/5/97: When the asynchronous download op completes, //it will delete this object BitmapDownloadParam* Param=new BitmapDownloadParam; OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_OPBITMAPDOWNLOAD); if (pOpDesc != NULL) { // get the temporary dir TCHAR TempDir[MAX_PATH]; FileUtil::GetTemporaryPath(MAX_PATH,TempDir); // get temp file name TCHAR TempFileName[256]; TCHAR Prefix[] = "BMP"; // the first three letters of the new file name FileUtil::GetTemporaryFileName(TempDir,Prefix,0,TempFileName); // extract the original filename INT32 lg = WebPath.Length()+1; char* TmpPath = new char[lg]; char* TmpPath2=TmpPath; ReverseString(WebPath, TmpPath); char* RevFileName = new char [lg]; char* FileNameTmp = RevFileName; while (*TmpPath2!='\\' && *TmpPath2!='/' && *TmpPath2!=NULL) *(FileNameTmp++) = *(TmpPath2++); *FileNameTmp = '\0'; // we download only if there is a file to download if (*RevFileName != '\0') { String_256 StrRevFileName(RevFileName); char* FileName = new char[lg]; ReverseString(StrRevFileName, FileName); //delete [] OutPath; String_256 StrFileName(TempDir); StrFileName += String_256(FileName); // fill in the struct (minimum necessary information) Param->type = TYPE_BITMAP; Param->priority = AsynchDownload::PRIORITY_NORMAL; Param->file = String_256(TempFileName); // temporary file name //Param->file = StrFileName; // temporary file name Param->strURL = WebPath; //Param->strDescription = "Bitmap file Download"; BOOL ok = TRUE; Param->Output = &ok; // other information relative to the filter //Param->m_Op = Op; // I need the Op Param->m_FileName = FileName; // original filename Param->m_DestDoc = DestDoc; // I also need the document Param->m_TagId = (INT32)TagId; // Id of tag associated with the bitmap Param->m_FileNum = FileNum; // current file Param->m_FileNumber = FileNumber; // number of files Param->m_PosTranslate = PosTranslate; // coordinates of the bitmap in the document Param->m_IsCenter = FALSE; // Invoke the operation pOpDesc->Invoke((OpParam*) Param); //Graham 2/6/97: Delete FileName delete [] FileName; } //Graham 2/6/97: And delete everything we need to delete delete [] TmpPath; delete [] RevFileName; } else return FALSE; } else // we can directly call the DoImportBitmap as the file is not a URL { //Rewritten by Graham 2/6/97 //First get the name of the file we're going to import String_256 szFileName = ListBitmaps->GetFileName(); //Then make a copy of the path of the file we are importing PathName Path=pthImportFile; //And set the file name of that path to the file name we are going //to import. Path.SetFileNameAndType(szFileName); //And import the bitmap if (!DoImportBitmap(TagId, Op, DestDoc, Path, FileNum, FileNumber, PosTranslate, FALSE, &NewName)) { // Make up an error string adding a default 'Problem loading images. This includes' and // then add the pathname. if (m_WarningsString.IsEmpty()) { m_WarningsString = String_256(_R(IDE_HTMLIMPORT_BADIMAGESINFILE)); } String_256 Sep(_R(IDS_TAG_ERROR_LIST_SEP)); String_256 Temp = Path.GetPath(); // Only add it if there is enough room to fit it all in if (Sep.Length() + Temp.Length() + m_WarningsString.Length() < m_WarningsString.MaxLength()) { m_WarningsString += Sep; m_WarningsString += Temp; } else { // Try using the filename plus extension only Temp = Path.GetFileName(); if (Sep.Length() + Temp.Length() + m_WarningsString.Length() < m_WarningsString.MaxLength()) { m_WarningsString += Sep; m_WarningsString += Temp; } } } } FileNum++; // Update the import position translation PosTranslate=GetImportPosition(DestDoc, FileNum); // Get the next element in the list ListBitmaps = (HTMLFileListItem*)HTMLList->GetNext(ListBitmaps); } return TRUE; } /******************************************************************************************** > static BOOL HTMLFilter::DoImportBitmap(HTMLTAG_TYPE TagId, SelOperation *Op, Document *DestDoc, PathName Path, INT32 FileNum, INT32 FileNumber, DocCoord& PosTranslate, BOOL IsCentre=FALSE) Author: Olivier_Gascoin (Xara Group Ltd) Created: 30/04/97 Inputs: TagId - tag associated with the bitmap Op - pointer to the operation that this input process is associated with. DestDoc - ppImportedBitmap - KernelBitmap for bitmap background Path - Path of the file FileNum - current file FileNumer - number of files Returns: TRUE Purpose: how to import (bitmap background or formatting bitmap) ********************************************************************************************/ BOOL HTMLFilter::DoImportBitmap(HTMLTAG_TYPE TagId, SelOperation *Op, Document *DestDoc, PathName Path, INT32 FileNum, INT32 FileNumber, DocCoord& PosTranslate, BOOL IsCentre, String_256* NewName) { BOOL ok = FALSE; KernelBitmap* pKernelBitmap = NULL; if (TagId == HTMLTAG_BODY) { // if it's body background then if (!ImportBitmap(Op, Path, &pKernelBitmap, NULL, FileNum+1, FileNumber, NewName)) return FALSE; Spread *pSpread = NULL; PORTNOTE("spread", "Multi-spread warning!") pSpread = GetFirstSpread(DestDoc); // can't be NULL if (!pSpread && !pKernelBitmap) return FALSE; // call the background op OpBackground::MakePageBackground(Op, pSpread, pKernelBitmap); return TRUE; } else { //Taken out by Graham 12/6/97 /*if (IsCentre) { // formatting, arbitrary position :-( PosTranslate.x = 288000; //PosTranslate.y = -(72000*0.2)*i; } */ //Modified by Graham 30/5/97 so it *doesn't* leak every bitmap it tries //to import! 8-) if (!ImportBitmap(Op, Path, &pKernelBitmap, &PosTranslate, FileNum+1, FileNumber, NewName)) return FALSE; } //And finally, set the name of the bitmap to our new name if (pKernelBitmap && NewName) pKernelBitmap->SetName(*NewName); return TRUE; } /******************************************************************************************** > static BOOL HTMLFilter::ParseHTMLFile(CCLexFile* pFile, HTMLFileList* HTMLList) Author: Olivier_Gascoin (Xara Group Ltd) (rewritten by Graham) Created: 30/04/97 Inputs: Op - pointer to the operation that this input process is associated with. pFile - The file that we should load DestDoc - Returns: TRUE if the input operation worked ok, FALSE if not. Purpose: Parse the html file then create the list of bitmaps and finally call ImportBitmap Errors: Fails (returns FALSE) if the document structure is incorrect, or if there is a problem with the bitmap. ********************************************************************************************/ BOOL HTMLFilter::ParseHTMLFile(CCLexFile* pFile, HTMLFileList* HTMLList) { //First check our parameters ERROR2IF(pFile == NULL, FALSE, "HTMLFilter::ParseHTMLFile NULL diskfile supplied"); ERROR2IF(HTMLList == NULL, FALSE, "HTMLFile::PArseHTMLFile NULL HTMLList supplied"); // Set up some variables BOOL IsCenter = FALSE; // this is used for formatting TCHAR* pTagName = new TCHAR[MAXTAGLENGTH]; TCHAR* pTagAttrib = new TCHAR[MAXTAGLENGTH]; TCHAR* pTokenBuf = new TCHAR[MAXTAGLENGTH]; //First initialise the lexer pFile->InitLexer(FALSE, TRUE); HTMLTAG_TYPE Token = HTMLTAG_UNKNOWN; BOOL ok = TRUE; //And now do the parsing until we reach the end of the file while (!pFile->IsEndOfHTMLFile()) { //First get an HTML token. This token will either be //a tag "" or text "xxxx". //The two parameters mean that we want to ignore any EOL characters //but we do not want the case to be corrected to upper case pFile->GetHTMLToken(TRUE, FALSE); //Now, if the HTML token is a tag if (pFile->IsHTMLTag()) { //Then get the name of the tag String_256 szTagName=pFile->GetHTMLTagName(); //Now try and find our token in the HTML table Token = FindTagId(szTagName); switch (Token) { case HTMLTAG_IMGSRC: { //It's an IMG tag. //Get the value of the SRC parameter. The "FALSE" indicates we shouldn't //correct the case of the value String_256 szValue=pFile->GetHTMLParameterValue(String_256("SRC"), FALSE); //And, if we found an SRC parameter value if (!szValue.IsEmpty()) { //Create a new HTMLFileListItem HTMLFileListItem* NewItem = new HTMLFileListItem((TCHAR*) szValue, Token, FALSE); //And try to add it to the list //If it doesn't get added, delete it if (!HTMLList->Add(NewItem)) delete NewItem; } } break; case HTMLTAG_EMBED: { //It's an EMBED tag. //Get the value of the SRC parameter. The "FALSE" indicates we shouldn't //correct the case of the value String_256 szValue=pFile->GetHTMLParameterValue(String_256("SRC"), FALSE); //And, if we found an SRC parameter value if (!szValue.IsEmpty()) { //Create a new HTMLFileListItem HTMLFileListItem* NewItem = new HTMLFileListItem((TCHAR*) szValue, Token, FALSE); //And try to add it to the list //If it doesn't get added, delete it if (!HTMLList->Add(NewItem)) delete NewItem; } } break; case HTMLTAG_BODY: { // It's a BODY tag //Get the value of the BACKGROUND parameter, if any String_256 szValue=pFile->GetHTMLParameterValue(String_256("BACKGROUND"), FALSE); //And if we found a value if (!szValue.IsEmpty()) { //Create a new HTMLFileListItem HTMLFileListItem* NewItem = new HTMLFileListItem((TCHAR*) szValue, Token, FALSE); //And try to add it to the list //If it doesn't get added, delete it if (!HTMLList->Add(NewItem)) delete NewItem; } } break; case HTMLTAG_INPUT: // e.g. : { //It's an input tag //Get the value of the TYPE parameter, if any String_256 szTypeValue=pFile->GetHTMLParameterValue(String_256("TYPE"), FALSE); //And if we found a TYPE parameter and its value was //IMAGE if (camStricmp(szTypeValue, "image")==0) { // Then look for an "SRC" parameter String_256 szSRCValue=pFile->GetHTMLParameterValue(String_256("SRC"), FALSE); //And if we found an SRC parameter value if (!szSRCValue.IsEmpty()) { //Then create a new HTMLFileListItem HTMLFileListItem* NewItem = new HTMLFileListItem((TCHAR*) szSRCValue, Token, FALSE); //And try to add it to the list //If it doesn't get added, delete it if (!HTMLList->Add(NewItem)) delete NewItem; } } } break; case HTMLTAG_UNUSED: case HTMLTAG_UNKNOWN: default: break; } } Token = HTMLTAG_UNKNOWN; } // We are now finished with the lexer pFile->DeinitLexer(); delete [] pTagName; delete [] pTagAttrib; delete [] pTokenBuf; // All ok return TRUE; } /******************************************************************************************** > static BOOL HTMLFilter::ImportBitmap(SelOperation *Op, PathName &Path, KernelBitmap** ppImportedBitmap, DocCoord* pPosTranslate, INT32 FileNum, INT32 FileNumber, String_256* NewName) Author: Olivier_Gascoin (Xara Group Ltd) Created: 14/04/97 Inputs: Op - Path = the path of the file to import ppImportedBitmap - The kernelBitmap I need to set the bitmap background up pPosTranslate - used for formatting FileNum - number of the file presently imported NewName - name of the bitmap Returns: TRUE if import ok Purpose: Errors: Fails (returns FALSE) if can't import the bitmap ********************************************************************************************/ BOOL HTMLFilter::ImportBitmap(SelOperation *Op, PathName &Path, KernelBitmap** ppImportedBitmap, DocCoord* pPosTranslate, INT32 FileNum, INT32 FileNumber, String_256* NewName) { BOOL ok = FALSE; if (!SGLibOil::FileExists(&Path)) return FALSE; // which filter to use ? Filter *pFilter = Filter::GetFirst(); while (pFilter != NULL) { // what kind of bitmap is it ? UINT32 Size = 1024; INT32 FileSize; ADDR FilterBuf = pFilter->LoadInitialSegment(Path, &Size, &FileSize); // If there has been a problem in the load initial segment then fail now. if (FilterBuf == NULL) { ok = FALSE; break; } // Inform any filters that we are about to do a HowCompatible call. // This would allow a set of filters which have common functionality hidden in a // filter that cannot import and cannot export handle this call and hence set // itself up. This would allow it to maybe cache a result which should only be // checked by the first filter in the group. pFilter->PreHowCompatible(); // Change this to be less than 8 as the filters like the Accusoft forms return // 8 and 9 to make sure that they are last in the chain. if (pFilter->HowCompatible(Path, FilterBuf, Size, FileSize) > 8) { ok = TRUE; CCFree(FilterBuf); // This is the filter! break; } //Free the initial segment CCFree(FilterBuf); // Try the next filter pFilter = Filter::GetNext(pFilter); } // filter found ? if (pFilter == NULL || !ok) return FALSE; // no filter found // now import bitmap // First off, we have to try and open the file CCDiskFile DiskFile(1024, FALSE, TRUE); // Get pointer to current doc 'cos we'll need it several times... Document* pCurDoc = Document::GetCurrent(); // open the file if (!DiskFile.open(Path, ios::in | ios::binary)) return FALSE; //Graham 15/7/97: Now, we want to import into the top left hand corner of the view DocView* pDocView=DocView::GetCurrent(); ERROR2IF(pDocView==NULL, FALSE, "HTMLFilter::DoImport - no current view"); ImportPosition posImport=pDocView->GetCentreImportPosition(); //And add on the amount by which to translate the bitmap if (pPosTranslate) { posImport.Position.x+=pPosTranslate->x; posImport.Position.y+=pPosTranslate->y; } // then import the file if (!pFilter->DoImport(Op, &DiskFile, pCurDoc, FALSE, NULL, ppImportedBitmap, pPosTranslate, NULL)) { // Close the file again if (DiskFile.isOpen()) DiskFile.close(); Error::ClearError(); // remove the error so it won't get reported return FALSE; } // Close the file again if (DiskFile.isOpen()) DiskFile.close(); return TRUE; } /******************************************************************************************** > BOOL HTMLFilter::GetTag(TCHAR* pTokenBuf, TCHAR* pTagName, const TCHAR* TokenBuffer) Author: Olivier_Gascoin (Xara Group Ltd) Created: 03/04/97 Inputs: TokenBuffer: e.g. : 'img src="image.gif"' Returns: TRUE if it had found another known HTML tag Purpose: extract the TAGNAME from the tokenbuf (e.g.: will extract 'img' from 'img src=image.gif') Errors: ********************************************************************************************/ BOOL HTMLFilter::GetTag(TCHAR* pTokenBuf, TCHAR* pTagName, const TCHAR* TokenBuffer) { if (TokenBuffer == NULL) return FALSE; // convert to lower case camStrcpy(pTokenBuf, TokenBuffer); pTokenBuf = _strlwr(pTokenBuf); // all known HTML tags for (INT32 i=0;i BOOL HTMLFilter::GetAttribute(const TCHAR* AttrName, TCHAR* pTokenBuf, TCHAR* pTagAttrib) Author: Olivier_Gascoin (Xara Group Ltd) Created: 03/04/97 Inputs: AttrName - store the name of the tag attribute (e.g. : img, or src....) Returns: TRUE if it had extracted the attribute Purpose: Extract the attribute from the tag Errors: ********************************************************************************************/ BOOL HTMLFilter::GetAttribute(const TCHAR* AttrName, const TCHAR* pTokenBuf, TCHAR* pTagAttrib) { // they shouldn't be NULL if (AttrName == NULL && pTokenBuf == NULL && pTagAttrib == NULL) return FALSE; // e.g. : 'img src=image.gif' // we move the pointer until 'src' const TCHAR* TokenBufTmp = pTokenBuf; TCHAR* TagAttribute = pTagAttrib; while (TRUE) { const TCHAR* AttrNameTmp = AttrName; // find the first occurence of the first letter of AttrName TokenBufTmp = strchr(TokenBufTmp, (INT32)(*AttrName)); if (TokenBufTmp == NULL) return FALSE; // extract "AttrName" from TokenBuf while ( *TokenBufTmp == *AttrNameTmp && *AttrNameTmp!=NULL && *TokenBufTmp!=NULL) { TokenBufTmp++; AttrNameTmp++; } if (*TokenBufTmp == NULL) return FALSE; if (*AttrNameTmp == NULL) break; } // move the pointer to reach the first letter while ( (*TokenBufTmp=='=' || *TokenBufTmp==' ' || *TokenBufTmp=='\t' || *TokenBufTmp=='\"') && *TokenBufTmp!=NULL) { TokenBufTmp++; } if (*TokenBufTmp == NULL) return FALSE; // extract the attribute while ( *TokenBufTmp!='\"' && *TokenBufTmp!=' ' && *TokenBufTmp!='\t' && *TokenBufTmp!=NULL) { *(TagAttribute++) = *(TokenBufTmp++); } *TagAttribute = '\0'; return TRUE; } /******************************************************************************************** > TCHAR* HTMLFilter::SearchStr(const char* A, const char* B) Author: Olivier_Gascoin (Xara Group Ltd) Created: 09/04/97 Inputs: A - string to search B- string to search for Returns: a pointer to the first occurence of B Purpose: Search for string B in string A Errors: ********************************************************************************************/ TCHAR* HTMLFilter::SearchStr(const char* A, const char* B) { if (A==NULL || B==NULL) return NULL; return ((TCHAR*)strstr(A, B)); } /******************************************************************************************** > DocCoord HTMLFilter::GetImportPosition(Document* pdocTarget, INT32 iPosNumber) Author: Graham_Walmsley (Xara Group Ltd) Created: 05/6/97 Inputs: pdocTarget - The document to import into iPosNumber - The number of the position Returns: The offset by which to offset bitmap number iPosNumber. Purpose: Finds the offset by which to offset the iPosNumber-th bitmap imported. The first bitmap imported is offset by 0,0. Then the next bitmap is offset by the standard offset which the duplication operation uses. And so on: the offset of the Nth bitmap equals the offset of the (N-1)th bitmap plus the duplication offset. This carries on until the offset is such so that the offset of the Mth bitmap would place it off the spread. Instead, then, the offset of the Mth bitmap is the horizontal component of the duplication offset. And then we go back to the general iterative rule. Not very well explained I'm afraid but I've got to get this done. Errors: Null parameters ********************************************************************************************/ DocCoord HTMLFilter::GetImportPosition(Document* pdocTarget, INT32 iPosNumber) { //First check our parameter ERROR2IF(pdocTarget==NULL, DocCoord(-1,-1), "HTMLFilter::GetFirstImportPosition - NULL parameter"); //This variable will remember how many times we have returned the import position //back to the top left hand corner INT32 iReturned=0; //Now get the first spread in the document PORTNOTE("spread", "Multi-spread warning!") Spread* psprFirst=pdocTarget->FindFirstSpread(); //Do some checking ERROR2IF(psprFirst==NULL, DocCoord(-1, -1), "HTMLFilter::GetFirstImportPosition - no spread in document"); //And get its bounding rectangle DocRect rectBounding; psprFirst->GetPagesRect(&rectBounding); //Now translate that rectangle so that its top left hand corner is at //0,0 DocCoord dcTopLeft(rectBounding.lo.x, rectBounding.hi.y); rectBounding.Translate(-dcTopLeft.x, -dcTopLeft.y); //Now, the first bitmap will be imported at 0,0 DocCoord dcThisPosition(0, 0); //And this is the standard duplication offset // DocCoord dcOffset(OpDuplicate::DuplicatePlacementX, OpDuplicate::DuplicatePlacementY); DocCoord dcOffset = pdocTarget->GetDuplicationOffset(); //Do the following a number of times equal to the number //of the bitmaps we are importing for (INT32 i=0; i