// $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