/******************************************************************************************** > BOOL PNGFilter::EndWriteToFile( ) Author: Neville_Humphrys (Xara Group Ltd) <*****@*****.**> Created: 14/5/96 Inputs: - Purpose: Cleans up after writing the bitmap data out to a file. Inherited classes override this to write in different file formats. This is slightly different to most other bitmap filters in that it is here that the data actually gets written out to file, after doing the transparency translation, if required. Returns: TRUE if worked, FALSE if failed. ********************************************************************************************/ BOOL PNGFilter::EndWriteToFile() { if (GeneratingOptimisedPalette()) return TRUE; // No need to output anything // Can reset the band number now. m_BandNumber = 0; PNGExportOptions* pPNGOptions = (PNGExportOptions*)GetBitmapExportOptions(); ERROR2IF(pPNGOptions == NULL, FALSE, "NULL Args"); ERROR3IF(!pPNGOptions->IS_KIND_OF(PNGExportOptions), "pPNGOptions isn't"); // Do the transparency translation just before we write out the data as a PNG. // This involves doing a 1 bpp export of the same area and using this to work // out which areas are transparent or not. // Only do this if the user has requested transparency and we outputting at 8bpp BOOL ok = TRUE; BOOL SaveDataOut = TRUE; if (BadExportRender) { // Delete our whitearea bitmap if (pTempBitmapMask != NULL) CCFree(pTempBitmapMask); pTempBitmapMask = NULL; } // Save the data out if required. Only if we exported ok. if (SaveDataOut && !BadExportRender) { if (ok) { // Now that we know the transparent index we can output the PNG header ok = DestPNG.OutputPNGHeader(OutputFile, NULL, pPNGOptions->WantInterlaced(), pPNGOptions->GetTransparencyIndex(), pPNGOptions->GetDepth() <= 8 ? pPNGOptions->GetLogicalPalette() : NULL); } // Actually write the destination bitmap out to the file showing an hourglass // and/or progress bar as we go. Always show the Exporting message. // Need to do in one go due to interlacing if (ok) { String_64 ProgressString(ExportingMsgID); ProgressString = GetExportProgressString(OutputFile, ExportingMsgID); BeginSlowJob(100, FALSE, &ProgressString); DestPNG.OutputPNGBits(OutputFile, DestPNG.GetDestBitmapBits()); EndSlowJob(); } } ASSERT(ok); return DestPNG.TidyUp(); }
BOOL GIFUtil::ReadFromFile( CCLexFile *File, LPBITMAPINFO *Info, LPBYTE *Bits, int *TransColour, int& nBitmapToRead, String_64 *ProgressString, BaseCamelotFilter *pFilter, UINT32* Delay, GIFDisposalMethod *Restore, UINT32 * pLeftOffset, UINT32 * pTopOffset, BOOL * pLocalPalette) { if ((nBitmapToRead > 1 && nBitmapToRead == m_nCurrentBitmap) || nBitmapToRead < 1) { ERROR3("GIFUtil::ReadFromFile() - can't read that bitmap"); return FALSE; } *Info = NULL; // in case of early exit *Bits = NULL; Transparent = -1; *TransColour = -1; // in case of early exit set to none int Background = 0; // background colour number !!! not used !!! Interlace = FALSE; // set interlace to false by default // Must set the exception throwing flag to True and force reporting of errors to False. // This means that the caller must report an error if the function returns False. // Any calls to CCLexFile::GotError will now throw a file exception and should fall into // the catch handler at the end of the function. BOOL OldThrowingState = File->SetThrowExceptions( TRUE ); BOOL OldReportingState = File->SetReportErrors( FALSE ); // If the caller has specified a string then assume they require a progress bar // Start it up. if (ProgressString != NULL) BeginSlowJob(100, FALSE, ProgressString); try { // If we want the first bitmap we'll assume we're at the start of the file & read the header if (nBitmapToRead == 1) { // place to store the global palette, if present, for later use lpGlobalPalette = NULL; // pointer to temporary palette store GlobalPaletteSize = 0; // size of the global palette found GIFINFOHEADER Header; // This is really sizeof(GIFINFOHEADER) but this returns 14 instead of 13 // as it rounds to the nearest word boundary const size_t HeaderSize = sizeof(char)* 6 + sizeof(WORD) * 2 + sizeof(BYTE) * 3; File->read( &Header, HeaderSize ); if (File->bad()) File->GotError( _R(IDE_FORMATNOTSUPPORTED) ); // Just double check that the signature is correct, if not then fail immediately if ( (strncmp(Header.giName, "GIF89a", 6) != 0) && (strncmp(Header.giName, "GIF87a", 6) != 0) ) File->GotError( _R(IDE_BADFORMAT) ); // Note the overall size of the GIF from the header, may be the animation size m_GlobalWidth = Header.giWidth; m_GlobalHeight = Header.giHeight; // flags word consists of:- // - bit 7 colour table flag = set if global colour table follows // - bits 6-4 colour resolution = bpps - 1 // - bit 3 sort flag = set global colour table sorted // - bits 3-0 size of global colour table = size is 2^(value+1) int ColorResolution = (((Header.giFlags >> 4) & 0x07) + 1); GlobalPaletteSize = 2 << (Header.giFlags & 0x07); Background = Header.giBackground; // int AspectRatio = Header.giAspect; TRACEUSER("Neville",_T("Gif Global Width = %d Height = %d\n"), m_GlobalWidth, m_GlobalHeight); TRACEUSER("Neville",_T("Gif ColorResolution = %d\n"), ColorResolution); // Check if we have a global colour map present or not, if so then read it in. if (BitSet(Header.giFlags, GLOBALCOLOURMAP)) { TRACEUSER("Neville",_T("Gif read global colour table size = %d\n"), GlobalPaletteSize); // Read in the global colour map into a palette structure for possible later use const size_t TotalPal = sizeof(RGBQUAD) * GlobalPaletteSize; lpGlobalPalette = (LPRGBQUAD)CCMalloc( TotalPal ); if (lpGlobalPalette==NULL) return FALSE; ReadColourMap(File, GlobalPaletteSize, lpGlobalPalette); } m_nCurrentBitmap = 0; m_NextImageStartPosition = 0; } // We now need to go through and process the data in this file which // should now consist off GIF blocks until we hit the end of file or // we have processed the lot. BOOL FileProcessed = FALSE; m_bImageRead = FALSE; unsigned char c; // Set up bad values so that the DIB alloc claim will fail if there // has been no GIFIMAGEBLOCK found // int Width = 0; // Width of bitmap // int Height = 0; // Height of bitmap // int BitsPerPixel = 0; //ColorResolution; // Colour depth required if (m_NextImageStartPosition != 0) { File->seekIn(m_NextImageStartPosition, ios::beg); m_NextImageStartPosition = 0; } while (!File->eof() && !File->bad() && !FileProcessed) { // Get the next character in the stream and see what it indicates // comes next in the file // Use Get as this will read the EOF character (255) and exit via the // File->eof() test rather than Read which will throw an exception. //File->read( &c, 1 ); File->get( (char&)c ); switch (c) { case ';': { // GIF terminator // Cannot assume that the terminator immediately follows the image data // Might have some extensions following the image data. FileProcessed = TRUE; nBitmapToRead = -1; break; } case '!': //EXTENSIONBLOCK: { // Extension ProcessExtension(File); break; } case ',': { // start of image character if (m_bImageRead) // another bitmap - save it for the next call to ReadFromFile() { if (m_NextImageStartPosition == 0) { // No transparency info for the next one so start here m_NextImageStartPosition = File->tellIn() - 1; } ++nBitmapToRead; FileProcessed = TRUE; break; } UINT32 LeftOffset = 0; UINT32 TopOffset = 0; BOOL LocalPalette = FALSE; // Should be followed by a GIFIMAGE BLOCK ProcessImageBlock(File, Info, Bits, &LeftOffset, &TopOffset, &LocalPalette); ++m_nCurrentBitmap; if (nBitmapToRead == m_nCurrentBitmap) { m_bImageRead = TRUE; } // return the values back to the caller if it desired them if (pLeftOffset) *pLeftOffset = LeftOffset; if (pTopOffset) *pTopOffset = TopOffset; if (pLocalPalette) *pLocalPalette = LocalPalette; break; } default: // We have found something other than what we are expecting // so fail with an error //File->GotError( IDE_BADFORMAT ); // Cannot do this as some files have random bits // e.g. galileo.gif has a random zero before the ; // colsec.gif has a rampant > at the end instead of ; if (m_bImageRead) { // We've already got something so ignore anything else in case it goes // completely wrong. FileProcessed = TRUE; nBitmapToRead = -1; } TRACE( _T("Unrecognized Character %x at %d\n"), (int)c, File->tellIn()); break; } } // If we reach here and the bitmap allocations are still null then no valid image // was found and so we should error now. // Might have just been a GIF file with extension tags in and no images! if (*Info == NULL || *Bits == NULL) File->GotError( _R(IDE_BADFORMAT) ); // We read the desired bitmap but the EOF came along before we could try anything else // Signal this is the last bitmap if (m_bImageRead && File->eof()) { TRACE( _T("GIF: Premature end of file") ); nBitmapToRead = -1; } // Return the transparency/delay/restore found to the caller. *TransColour = Transparent; if (Delay) { *Delay = m_Delay; } if (Restore) { *Restore = m_Restore; } // Free up the bit of memory for a palette we grabbed, if present & no more images to read if (lpGlobalPalette && nBitmapToRead == -1) { CCFree(lpGlobalPalette); lpGlobalPalette = NULL; } // If started, then stop then progress bar if (ProgressString != NULL) EndSlowJob(); // Must set the exception throwing and reporting flags back to their entry states File->SetThrowExceptions( OldThrowingState ); File->SetReportErrors( OldReportingState ); // er, we seem to have finished OK so say so return TRUE; }
INT32 LibraryFile::Init(SuperGallery *ParentGal, PathName *APath, SGLibType Type, BOOL Updated, BOOL DoScroll) { #ifndef EXCLUDE_GALS if(ParentGal == NULL || APath == NULL || !Libraries.IsEmpty()) { ERROR3("LibraryFile::Init - NULL parameters are illegal OR Init called > 1 times"); if(!Libraries.IsEmpty()) return(Libraries.GetCount()); else return 0; } BOOL ok = TRUE; // Tidy up Path a bit String_256 OurPath(APath->GetPath()); LibraryFile::TidyUpSubPath(&OurPath); // Now point Path to the new pathname PathName ModifiedPath(OurPath); PathName *Path = &ModifiedPath; if(!ModifiedPath.IsValid()) { ERROR3("LibraryFile::Init -> Modified library path is invalid"); return 0; } // Remember the pathname and type MyPath = *Path; MyType = Type; ParentGallery = ParentGal; if(ParentGallery->IsKindOf(CC_RUNTIME_CLASS(LibraryGallery))) ParentLibraryGallery = (LibraryGallery *)ParentGal; else { ERROR3("LibraryFile::Init passed a non-library gallery - yikes..."); return 0; } // Need to reset the Quiet status before a stream of Library::Init calls ParentLibraryGallery->SetQuietStatus(FALSE); BOOL Retry = TRUE; while(Retry) { Retry = FALSE; // Would be nice to have a way of adding a file to a path in PathName... Is there one ? if(!SGLibOil::FileExists(Path)) { // We're opening the font gallery, but can't find the font library path - don't warn if(Type == SGLib_Font) return 0; // tell the user that the directory doesn't exist String_256 WarnMsg; String_256 DefaultIndex; String_256 IndexDesc; BOOL CanGenerate; ok = LibraryFile::GetSubIndexDetails(ParentLibraryGallery, &DefaultIndex, &IndexDesc, &CanGenerate); String_256 TmpPath(Path->GetLocation(FALSE)); LibraryFile::TidyUpSubPath(&TmpPath); // Taken out by Graham 30/10/97: If the gallery had no directory specified, //we used to throw a warning which said "do you want to specify another folder?" //We don't do this any more, because the default is to open all galleries empty and //then download stuff from the Xara web site #if 0 WarnMsg.MakeMsg(_R(IDS_BROWSE_OR_SCAN), (TCHAR *)IndexDesc, (TCHAR *)TmpPath); Error::SetError(0, WarnMsg, 0); INT32 ButtonPressed = InformWarning(0, _R(IDS_BROWSE), _R(IDS_RETRY), _R(IDS_CANCEL)/*, _R(IDS_HELP)*/); #else // WEBSTER INT32 ButtonPressed = 3; #endif // WEBSTER TRACEUSER( "Richard", _T("ButtonPressed: %d\n"), ButtonPressed); Error::ClearError(); switch(ButtonPressed) { case 1: { // Open the Browse dialog (or the Add.. dialog as it seems to be called now) PathName ThePath(*Path); // This returns FALSE if Cancel was hit, or an error occurred. if(!SGLibOil::GetLibPath(ParentLibraryGallery, &ThePath, CanGenerate, Type)) { ERROR3("GetLibPath returned FALSE in LF::Init"); return 0; } else { ModifiedPath = ThePath; if(!ModifiedPath.IsValid()) { ERROR3("LibraryFile::Init -> scanned library path is invalid"); return 0; } // Remember the pathname MyPath = ThePath; switch(Type) { case SGLib_ClipArt: case SGLib_Bitmap: LibClipartSGallery::DefaultLibraryPath = MyPath.GetPath(); LibClipartSGallery::ClipartPath = LibClipartSGallery::DefaultLibraryPath; break; case SGLib_ClipArt_WebThemes: LibClipartSGallery::DefaultLibraryPath = MyPath.GetPath(); LibClipartSGallery::WebThemePath = LibClipartSGallery::DefaultLibraryPath; break; #ifndef STANDALONE case SGLib_Texture: case SGLib_Fractal: LibFillsSGallery::DefaultLibraryPath = MyPath.GetPath(); break; case SGLib_Font: // WEBSTER-Martin-09/01/97 - Put back by Ranbir. //#ifndef WEBSTER FontsSGallery::DefaultLibraryPath = MyPath.GetPath(); break; // Not in webster so we get the error below //#endif // WEBSTER #endif default: ERROR2(FALSE,"Library::ScanForLocation Type not present!"); break; } } break; } case 2: Retry = TRUE; #if 0 { // Scan String_256 Result; if(!Library::ScanForLocation(Type, &Result)) { ERROR3("No libraries found..."); return 0; } if(!ModifiedPath.SetPathName(Result)) { ERROR3("LibraryFile::Init -> scanned library path is invalid"); return 0; } // Remember the pathname and type MyPath = *Path; } #endif break; case 3: // Cancel return 0; } } } // Wipe libraries added to gallery for scroll / redraw purposes... InitScrollRedrawSystem(); // Check the actual path exists if(SGLibOil::FileExists(Path)) { // Would be nice to have a way of adding a file to a path in PathName... Is there one ? String_256 IndexFile((const TCHAR *)Path->GetPath(TRUE)); // "%s\\XaraInfo\\index.txt" IndexFile += String_16(_R(IDS_LIBRARIES_XARAINFO_DIRNAME)); IndexFile += TEXT("\\") + String_16(_R(IDS_LIBRARIES_INDEX_FILENAME)); PathName IndexFilePath(IndexFile); if(!IndexFilePath.IsValid()) { ERROR3("LibraryFile::Init indexfilepath is invalid"); return 0; } CCDiskFile MainIndex; if (!MainIndex.InitLexer(FALSE)) { // SetError! ERROR3("LibraryFile::LibraryFile InitLexer failed"); return(0); } if(SGLibOil::FileExists(&IndexFilePath)) { // Count lines in index file INT32 Count = CountLines(&IndexFilePath); TRACEUSER( "Richard", _T("%d lines in index file\n"), Count); // Used for the percentage display INT32 CurrentGroupNumber = 0; // Just in case there's a slow job already going on... SmashSlowJob(); String_64 SlowJob(_R(IDS_LIBRARY_SCANNING)); BeginSlowJob(Count, FALSE, &SlowJob); // Now use the index file to create each group in turn if (MainIndex.open(IndexFilePath, ios::in)) { MainIndex.SetWhitespace(""); // Setting this to blank lets us read non-"'d strings MainIndex.SetDelimiters(","); // ,s delimit our fields MainIndex.SetCommentMarker('#'); // #'d lines are commented out MainIndex.SetStringDelimiters(""); // No string delimiters String_64 Directory; String_64 Description; String_64 SubIndex; String_64 Kind; LexTokenType TT; BOOL EscapePressed = FALSE; while(ok && !EscapePressed) { if(!MainIndex.GetToken()) break; // Get SubLib directory name // Keep reading tokens until we hit a normal one... (skips line ends and // comments for us TT = MainIndex.GetTokenType(); while (TT != TOKEN_NORMAL && ok) { ok = MainIndex.GetToken(); if(!ok) break; TT = MainIndex.GetTokenType(); ok = (TT != TOKEN_EOF); if(!ok) break; } if(!ok) break; Directory = MainIndex.GetTokenBuf(); KillLeadingSpaces(&Directory); if(!MainIndex.GetToken()) break; // Get ',' if(!MainIndex.GetToken()) break; // Get Description String_256 Description256; Description256 = MainIndex.GetTokenBuf(); KillLeadingSpaces(&Description256); Description256.Left(&Description, 60); if(!MainIndex.GetToken()) break; // Get ',' if(!MainIndex.GetToken()) break; // Get Sub Library Index name SubIndex = MainIndex.GetTokenBuf(); KillLeadingSpaces(&SubIndex); if(!MainIndex.GetToken()) break; // Get ',' if(!MainIndex.GetToken()) break; // Get type of files in sublib Kind = MainIndex.GetTokenBuf(); KillLeadingSpaces(&Kind); BOOL Match = FALSE; Match = ParentLibraryGallery->CheckForIndexMatch(&Kind); if(Match) { // Show status of additions EscapePressed = !ContinueSlowJob(CurrentGroupNumber++); // Sort pathname of sublib directory out String_256 SubP(Path->GetPath(TRUE)); SubP += Directory; PathName SubPath(SubP); if(!SubPath.IsValid()) { ERROR3("LibraryFile::Init - invalid subpath"); if(MainIndex.isOpen()) MainIndex.close(); EndSlowJob(); return 0; } // Go ahead and add the new group if(ok) { // Create the sub lib Library *NewSubLib = new Library; if (NewSubLib != NULL) { // Create the new group in the gallery (note the TRUE for create a virtualised one if // we can to save time / memory) if(NewSubLib->Init(ParentGal, &SubPath, &Description, &SubIndex, Type, Updated, TRUE)) { Libraries.AddTail(NewSubLib); // Keep track of libraries added for redraw purposes... AddNewFolderToScrollRedrawSystem(NewSubLib); } else { // This check is new, should be ok... delete NewSubLib; NewSubLib = NULL; ERROR3("Library::Init failed in LibraryFile::Init"); ok = FALSE; } } } } } } else { // Failed to open the index file... // SetError?! ERROR3("LibraryFile::LibraryFile couldn't open index file"); ok = FALSE; } EndSlowJob(); } else { // The directory given had no XaraInfo\index.txt file, maybe it's a sublib, check // For defaults... ok = CheckForSubIndexes(ParentGal, Path, Type, Updated); } // reclaim lexer-buffer memory MainIndex.DeinitLexer(); // And close the file if(MainIndex.isOpen()) MainIndex.close(); // Scroll / redraw the newly added groups... if(DoScroll) DoScrollRedraw(); } else { TRACEUSER( "Richard", _T("Path doesn't exist\n")); } // And return the number of items created return(Libraries.GetCount()); #endif return 0; }
BOOL DocumentFontDropDown::FillInFontList(Document * WorkDoc) { ERROR2IF(ParentDlg == NULL, FALSE, "FontDropDown not properly initialised"); BeginSlowJob(); SetListRedraw(FALSE); // Disable redraw while updating KillList(); // Delete combobox contents and empty the fonts list //ClearList(); // Delete combobox contents // Setup the static class pointer variable so we can add things to this dropdown... CurrentFontDropDown = (void *)this; //if(Fonts.GetCount() == 0) //{ if (WorkDoc == NULL) { // Fill in one item in the list which is no document fonts being used String_8 DashString(_R(IDS_K_FINFODLG_DASH)); TheTopItem.FontName = DashString; TheTopItem.Type = FC_UNDEFINED; //AddFontToList((TCHAR*)&TheTopItem.FontName, TheTopItem.Type); } else { // Build the font list for the specified document // This will NOT be alphabetical FontList DocFonts; DocFonts.Build(WorkDoc); FontListItem* FontItem = DocFonts.GetFirstItem(); if (FontItem == NULL) { // Fill in one item in the list which is no document fonts being used TheTopItem.FontName = _R(IDS_NO_FONTSINDOC); TheTopItem.Type = FC_UNDEFINED; //AddFontToList((TCHAR*)&TheTopItem.FontName, TheTopItem.Type); } else { //BOOL FirstInList = TRUE; // fill up the list while (FontItem != NULL) { // get the name String_64 Name = FontItem->GetFontName(); WORD Handle = FONTMANAGER->GetFontHandle(&Name); // check the style INT32 Style = FontItem->GetFontStyle(); if(Style & 1) Name += _T(" -Bold"); if(Style & 2) Name += _T(" -Italic"); if(Handle > 0) { if (FONTMANAGER->IsFontReplaced(Handle)) Name += _T(" *"); } FontClass Type = FontItem->GetFontClass(); AddFontToList(Name, Type); FontItem = DocFonts.GetNextItem(FontItem); ContinueSlowJob(); } } } //} // Work out the top item, if any, on the alphabetically sorted list // ready for putting in the top combo box item FontDropItem *pTopItem = (FontDropItem *)Fonts.GetHead(); if (pTopItem != NULL) { // Fill in the top item in the list TheTopItem.FontName = pTopItem->FontName; TheTopItem.Type = pTopItem->Type; } ListItem *Item = Fonts.GetHead(); while (Item != NULL) { // Add the font in the list to the combo box AddItem((void *) Item); // Try the next item Item = Fonts.GetNext(Item); } // Re-enable redraw SetListRedraw(TRUE); // We have no concept of a selected font SetSelectedIndex(-1); EndSlowJob(); return(TRUE); }
BOOL StringToBitmap::SaveBitmap(KernelBitmap *Bitmap, PathName *Path) { BOOL ok = TRUE; // if(Bitmap->GetBPP() != 32) // { // TRACEUSER( "Richard", _T("Can only save converted 32bpp thumbnails")); // return FALSE; // } // Get the file ready for outputting CCDiskFile OutputFile; PathName TmpPath(*Path); ok = OutputFile.open(TmpPath, ios::out | ios::binary); if(!ok) ERROR3("s2bmp OutputFile.open returned false"); if(!ok) return FALSE; // Always output at 8bpp or 32bpp const UINT32 OutputDepth = Bitmap->GetBPP(); if(OutputDepth != 8 && OutputDepth != 32) { ERROR3("Wrong bpp for saving bmp in fontpgen"); return FALSE; } // Extract the header info and write it to the file first BitmapInfo Info; BitmapInfo *lpInfo = &Info; ok = Bitmap->ActualBitmap->GetInfo(lpInfo); if(!ok) ERROR3("s2bmp Bitmap->ActualBitmap->GetInfo(lpInfo) returned false"); if(!ok) return FALSE; LPBITMAPINFOHEADER pBMI =&(((WinBitmap *)(Bitmap->ActualBitmap))->BMInfo->bmiHeader); ok = (pBMI!=NULL); if(!ok) ERROR3("s2bmp pBMI!=NULL returned false"); if(!ok) return FALSE; UINT32 Ysize = pBMI->biHeight; // Sort the palette out LPLOGPALETTE lpPalette = NULL; DWORD space[258]; // bodge (256 entries + 2 DWORDS) if(OutputDepth<=8) { //DWORD *space = malloc(sizeof(DWORD) * (2<<OutputDepth)+4); // bodge! lpPalette = (LPLOGPALETTE)(void *)(space); memcpy(lpPalette->palPalEntry /*dest*/, (pBMI+1/*ptr arith*/)/*src*/, (pBMI->biClrUsed)*sizeof(DWORD)); lpPalette->palVersion = 0x300; lpPalette->palNumEntries = (unsigned short)(pBMI->biClrUsed); } // Set up the compression flag only if the output depth is correct UINT32 Compress = BI_RGB; // if (OutputDepth==4) Compress = BI_RLE4; // if (OutputDepth==8) Compress = BI_RLE8; // Write header to output file OutputDIB DestDIB; BeginSlowJob(100, TRUE, &(String_64)"Creating thumbnail"); ok = DestDIB.StartFile( &OutputFile, pBMI, lpPalette, OutputDepth, // actual file depth Compress, // compression (BI_RGB = none) (UINT32) Ysize, // all of it 100); // size of progress bar if(!ok) ERROR3("DestDIB.StartFile returned false"); if(!ok) EndSlowJob(); if(!ok) return FALSE; // write main data to the output file ok = DestDIB.WriteBlock(0, Ysize, ((WinBitmap *)(Bitmap->ActualBitmap))->BMBytes, (UINT32) Bitmap->GetBPP()); if(!ok) ERROR3("DestDIB.WriteBlock returned false"); if(!ok) EndSlowJob(); if(!ok) return FALSE; // Tidy up the file before killing the object ok = DestDIB.TidyUp(); EndSlowJob(); if(!ok) ERROR3("DestDIB.TidyUp returned false"); if(!ok) return FALSE; return TRUE; }
/******************************************************************************************** > void OpBaseConvertPathSegment::Do(OpDescriptor*) Author: Peter_Arnold (Xara Group Ltd) <*****@*****.**> Created: 16/8/95 Inputs: OpDescriptor (unused) Purpose: Performs the common SelRange scanning part of converting path segments. Calls the ProcessSegment function in derived classes to do the actual processing Errors: - SeeAlso: - ********************************************************************************************/ void OpBaseConvertPathSegment::Do(OpDescriptor*) { #ifndef STANDALONE // Obtain the current selections and the first node in the selection SelRange* Selected = GetApplication()->FindSelection(); BOOL ok = (Selected != NULL); // Start the op BeginSlowJob(); if (ok) ok = DoStartSelOp(TRUE,TRUE); // Check with the selrange it is ok to run this op ObjChangeFlags cFlags; ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this); if (ok) { if (!Selected->AllowOp(&ObjChange)) { EndSlowJob(); FailAndExecute(); End(); return; } } Node* pNode = Selected->FindFirst(); NodePath* ThisPath = NULL; while (ok && (pNode != NULL)) { // we're only interested in NodePaths which have selected points BOOL DoThisNode = pNode->IsNodePath(); if (DoThisNode) DoThisNode = (((NodePath*)pNode)->InkPath.IsSubSelection()); if (DoThisNode) DoThisNode = (((NodePath*)pNode)->IsPathAllowable()); if ( DoThisNode ) { // for convenience, cast the pointer to a pointer to a NodePath ThisPath = (NodePath*)pNode; // First get pointers to the arrays PathVerb* Verbs = NULL; PathFlags* Flags = NULL; DocCoord* Coords = NULL; ThisPath->InkPath.GetPathArrays(&Verbs, &Coords, &Flags); INT32 NumCoords = ThisPath->InkPath.GetNumCoords(); BOOL PrevSelected = FALSE; INT32 PrevPos = 0; // Set the NeedToRender flags INT32 loop; for (loop = 0; loop < NumCoords; loop++) { if (Flags[loop].IsEndPoint && Flags[loop].IsSelected) Flags[loop].NeedToRender = TRUE; else Flags[loop].NeedToRender = FALSE; } // Force a re-draw of the place where the path used to be if (ok) ok = (RecalcBoundsAction::DoRecalc(this, &UndoActions, ThisPath, TRUE) != AC_FAIL); // loop through the points for (loop = 0; loop<NumCoords; loop++) { if (Flags[loop].IsEndPoint) { // its an endpoint if (Flags[loop].IsSelected) { // which is selected if (PrevSelected && ((Verbs[loop] & ~PT_CLOSEFIGURE) == GetProcessPathType()) ) { // and the previous was selected and it's a processable segment if (ok) ok = ProcessSegment(ThisPath, &loop, PrevPos); // Recache array pointers ThisPath->InkPath.GetPathArrays(&Verbs, &Coords, &Flags); NumCoords = ThisPath->InkPath.GetNumCoords(); Flags[loop].NeedToRender = TRUE; } PrevSelected = TRUE; PrevPos = loop; } else PrevSelected = FALSE; } } // Having finished processing this path go round and smooth it. DocCoord NewCoord; for (loop = 0; (ok && (loop < NumCoords)); loop++) { if (Verbs[loop] == PT_BEZIERTO && !(Flags[loop].IsEndPoint) && Flags[loop].IsSmooth) { NewCoord = ThisPath->InkPath.SmoothControlPoint(loop); if (ok && (NewCoord != Coords[loop])) { ok = DoAlterPathElement(ThisPath, loop, NewCoord, Flags[loop], Verbs[loop], FALSE); ThisPath->InkPath.GetPathArrays(&Verbs, &Coords, &Flags); } } } ThisPath->InvalidateBoundingRect(); // Force a redraw of the place where the path is now. if (ok) ok = (RecordBoundsAction::DoRecord(this, &UndoActions, ThisPath, TRUE) != AC_FAIL); } pNode = Selected->FindNext(pNode); } if (ok) { ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this); if (!UpdateChangedNodes(&ObjChange)) { FailAndExecute(); End(); return; } } EndSlowJob(); if (!ok) { FailAndExecute(); InformError(); } #endif End(); }
void OpReversePath::Do (OpDescriptor*) { // Obtain the current selections and the first node in the selection SelRange* Selected = GetApplication()->FindSelection(); BOOL ok = (Selected != NULL); // Start the op BeginSlowJob(); if (ok) ok = DoStartSelOp(TRUE,TRUE); // Check with the selrange it is ok to run this op ObjChangeFlags cFlags; ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this); if (ok) { if (!Selected->AllowOp(&ObjChange)) { EndSlowJob(); FailAndExecute(); End(); return; } } Node* pNode = Selected->FindFirst(); NodePath* ThisPath = NULL; //Document* pDocument = GetWorkingDoc(); while (ok && (pNode != NULL)) { // we're only interested in NodePaths which have selected points BOOL DoThisNode = pNode->IsNodePath(); //if (DoThisNode) // DoThisNode = (((NodePath*)pNode)->InkPath.IsSubSelection()); if (DoThisNode) DoThisNode = (((NodePath*)pNode)->IsPathAllowable()); if ( DoThisNode ) { // for convenience, cast the pointer to a pointer to a NodePath ThisPath = (NodePath*)pNode; // First get pointers to the arrays PathVerb* Verbs = NULL; PathFlags* Flags = NULL; DocCoord* Coords = NULL; ThisPath->InkPath.GetPathArrays(&Verbs, &Coords, &Flags); INT32 NumCoords = ThisPath->InkPath.GetNumCoords(); // BOOL PrevSelected = FALSE; // INT32 PrevPos = 0; ObjChangeFlags cFlags; cFlags.TransformNode = TRUE; ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,ThisPath,this); if (!ThisPath->AllowOp(&ObjChange, TRUE)) { return; } // Set the NeedToRender flags for (INT32 loop = 0; loop < NumCoords; loop++) { if (Flags[loop].IsEndPoint && Flags[loop].IsSelected) Flags[loop].NeedToRender = TRUE; else Flags[loop].NeedToRender = FALSE; } // Force a re-draw of the place where the path used to be if (ok) ok = (RecalcBoundsAction::DoRecalc(this, &UndoActions, ThisPath, TRUE) != AC_FAIL); DoReversePath (ThisPath); // Force a redraw of the place where the path is now. if (ok) ok = (RecordBoundsAction::DoRecord(this, &UndoActions, ThisPath, TRUE) != AC_FAIL); } pNode = Selected->FindNext(pNode); } if (ok) { ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this); if (!UpdateChangedNodes(&ObjChange)) { FailAndExecute(); End(); return; } } EndSlowJob(); if (!ok) { FailAndExecute(); InformError(); } End(); }
PNGProgressBar::~PNGProgressBar() { // If started, then stop then progress bar if (show_progress_bar) EndSlowJob(); }
void OpAlign::DoWithParam(OpDescriptor* pOp, OpParam* pAlignParam) { // DMc alterations so that this works with compound nodes SelRange Selection(*(GetApplication()->FindSelection())); RangeControl rg = Selection.GetRangeControlFlags(); rg.PromoteToParent = TRUE; Selection.Range::SetRangeControl(rg); DocRect SelRect = Selection.GetBoundingRect(); DocRect TargetRect; TargetRect.MakeEmpty(); INT32 NumObjs = Selection.Count(); AlignParam* pAlign =(AlignParam*)pAlignParam; BOOL moved=FALSE; // set to TRUE if any object is moved BeginSlowJob(-1,FALSE); BOOL OK=DoStartTransOp(FALSE); // find parent spread of first object in selection Node* pFirstNode=NULL; Spread* pSpread =NULL; if (OK) { pFirstNode=Selection.FindFirst(); if (pFirstNode!=NULL) pSpread=pFirstNode->FindParentSpread(); OK=(pSpread!=NULL); if (!OK) ERROR2RAW("OpAlign::DoWithParam() - could not find parent spread"); } // Find the size of the target rectangle if (pAlign->target==ToSelection) TargetRect=SelRect; else { Page* pPage=pSpread->FindFirstPageInSpread(); while (pPage) { DocRect PageRect=pPage->GetPageRect(); if (pAlign->target==ToSpread || SelRect.IsIntersectedWith(PageRect)) TargetRect=TargetRect.Union(PageRect); pPage=pPage->FindNextPage(); } } // allocate all dynamic memory required Node** pObj=NULL; ObjInfo* x =NULL; ObjInfo* y =NULL; INT32* dx =NULL; INT32* dy =NULL; if (OK) ALLOC_WITH_FAIL(pObj,(Node**) CCMalloc(NumObjs*sizeof(Node*)), this); if (pObj!=NULL) ALLOC_WITH_FAIL(x, (ObjInfo*)CCMalloc(NumObjs*sizeof(ObjInfo)),this); if ( x!=NULL) ALLOC_WITH_FAIL(y, (ObjInfo*)CCMalloc(NumObjs*sizeof(ObjInfo)),this); if ( y!=NULL) ALLOC_WITH_FAIL(dx, (INT32*) CCMalloc(NumObjs*sizeof(INT32)), this); if ( dx!=NULL) ALLOC_WITH_FAIL(dy, (INT32*) CCMalloc(NumObjs*sizeof(INT32)), this); OK=(dy!=NULL); // if memory claimed OK and target rect not empty proceed with op // (ie. do nothing if 'within page(s)' when no object on a page) DocRect EmptyRect; if (OK && TargetRect!=EmptyRect) { // create an array of pointers to objects (nodes) to be affected Node* pNode=Selection.FindFirst(); INT32 i=0; while (pNode!=NULL) { if (pNode->IsBounded() && !((NodeRenderableBounded*)pNode)->GetBoundingRect(TRUE).IsEmpty()) pObj[i++]=pNode; pNode=Selection.FindNext(pNode); } NumObjs=i; // cache x & y info in separate arrays so they can be sorted separately XLONG SumObjWidths =0; XLONG SumObjHeights=0; for (i=0; i<NumObjs; i++) { DocRect ObjRect=((NodeRenderableBounded*)pObj[i])->GetBoundingRect(); x[i].i=i; x[i].lo=ObjRect.lo.x; x[i].hi=ObjRect.hi.x; SumObjWidths+=ObjRect.hi.x-ObjRect.lo.x; y[i].i=i; y[i].lo=ObjRect.lo.y; y[i].hi=ObjRect.hi.y; SumObjHeights+=ObjRect.hi.y-ObjRect.lo.y; } // for each object, calculate the x and y displacements independently AlignOneAxis(pAlign->h,NumObjs,SumObjWidths, TargetRect.lo.x,TargetRect.hi.x,x,dx); AlignOneAxis(pAlign->v,NumObjs,SumObjHeights,TargetRect.lo.y,TargetRect.hi.y,y,dy); // apply the x and y displacements simultaneously to each object for (i=0; i<NumObjs; i++) if (dx[i]!=0 || dy[i]!=0) { moved=TRUE; Trans2DMatrix* pMatrix=new Trans2DMatrix(dx[i],dy[i]); DoTransformNode((NodeRenderableInk*)pObj[i],pMatrix); } } // free up any memory which was allocated CCFree(dx); CCFree(dy); CCFree(x); CCFree(y); CCFree(pObj); if (moved) { Document::GetSelected()->ForceRedraw(pSpread, TargetRect); GetApplication()->UpdateSelection(); } else FailAndExecute(); End(); EndSlowJob(); }
/******************************************************************************************** > static BOOL PNGFilter::WriteToFile ( CCLexFile* File, LPBITMAPINFO Info, LPBYTE Bits, String_64* ProgressString = NULL ) Author: Neville_Humphrys (Xara Group Ltd) <*****@*****.**> Created: 26/4/96 Inputs: File An opened CCFile that can be written to. It should be positioned at the start. Caller is responsible for closing it. The file needs to be in Binary mode. Info BITMAPINFO structure for the dib. Bits The bitmap data itself ProgressString allows the user to specify whether they require a progress hourglass or not. If NULL then none is shown, otherwise an progress bar is shown using the text supplied. Defaults to NULL i.e. no progress bar. Outputs: - Returns: TRUE if worked, FALSE if failed (error will be set accordingly but not reported) Purpose: Write a bitmap in memory straight out as a PNG to file with no rendering or conversion between different colour depths (apart from 32 to 24) or resolution. ***Errors on 16-bit builds*** A progress hourglass can be shown if required. This function is used by the save bitmap button on the bitmap gallery. All other bitmap export uses the OutputDIB class instead as this copes with using a render region and converting from 32 to the destination format. (caller should close file) Errors: Calls SetError on FALSE returns. Scope: Static SeeAlso: AccusoftFilters::WriteToFile; DIBUtil::WriteToFile; ********************************************************************************************/ BOOL PNGFilter::WriteToFile( CCLexFile* File, LPBITMAPINFO Info, LPBYTE Bits, String_64* ProgressString ) { #ifdef DO_EXPORT ERROR2IF(File==NULL,FALSE,"PNGFilter::WriteToFile File pointer is null"); ERROR2IF(Info==NULL,FALSE,"PNGFilter::WriteToFile BitmapInfo pointer is null"); ERROR2IF(Bits==NULL,FALSE,"PNGFilter::WriteToFile Bits pointer is null"); // If the caller has specified a string then assume they require a progress bar // Start it up. if (ProgressString != NULL) BeginSlowJob(100, FALSE, ProgressString); // BITMAPINFO consists of:- // BITMAPINFOHEADER bmiHeader; // RGBQUAD bmiColors[1]; LPBITMAPINFOHEADER pInfoHeader = &Info->bmiHeader; ERROR2IF(pInfoHeader==NULL,FALSE,"PNGFilter::WriteToFile BitmapInfoHeader pointer is null"); LPRGBQUAD pPalette = &(Info->bmiColors[0]); ERROR2IF(pPalette==NULL,FALSE,"PNGFilter::WriteToFile palette pointer is null"); // Set up our format type flags. BOOL Interlace = TRUE; // Use interlace or not INT32 Transparent = -1; // colour or -1 = no transparency BOOL WantTransparent = FALSE; switch (s_FilterType) { default: case PNG: Interlace = FALSE; WantTransparent = FALSE; break; case PNG_INTERLACED: Interlace = TRUE; WantTransparent = FALSE; break; case PNG_TRANSPARENT: Interlace = FALSE; WantTransparent = TRUE; break; case PNG_TRANSINTER: Interlace = TRUE; WantTransparent = TRUE; break; } if (WantTransparent) { // We want to try and output the transparency if possible ... // Scan through the palette, and try and find an index with // the transparency flag set INT32 cols = Info->bmiHeader.biClrUsed; // If we have zero colours on a bitmap which is 8bpp or less then this is bad. // This should be translated as the maximum number of colours allowed if (Info->bmiHeader.biBitCount <= 8 && cols == 0) cols = 1 << Info->bmiHeader.biBitCount; for (INT32 i = 0; i < cols; i++) { if (Info->bmiColors[i].rgbReserved == 0xFF) { Transparent = i; TRACEUSER( "Neville", _T("PNG output with transp index of %d\n"),Transparent); break; } } } // Output the PNG data BOOL ok = TRUE; // Output a PNG header for this file, using the RGBQUAD palette rather than a LOGPALETTE if (Transparent == -1) ok = DestPNG.OutputPNGHeader(File, pInfoHeader, Interlace, -1, NULL, pPalette); else ok = DestPNG.OutputPNGHeader(File, pInfoHeader, Interlace, Transparent, NULL, pPalette); // Now write out the bitmap data itself. if (ok) ok = DestPNG.OutputPNGBits(File, Bits, TRUE); // If started, then stop then progress bar if (ProgressString != NULL) EndSlowJob(); // er, we seem to have finished OK so say so return TRUE; #else return FALSE; #endif }