/* For general Scribus (>=1.3.2) copyright and licensing information please refer to the COPYING file provided with the program. Following this notice may exist a copyright and/or license notice that predates the release of Scribus 1.3.2 for which a new license (GPL+exception) is in place. */ /*************************************************************************** begin : 2005 copyright : (C) 2005 by Franz Schmid email : Franz.Schmid@altmuehlnet.de copyright : (C) 2005 by Craig Bradney email : cbradney@zip.com.au ***************************************************************************/ /*************************************************************************** * * * ScMW program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "documentchecker.h" #include "page.h" #include "pageitem.h" #include "sclayer.h" #include "scribusdoc.h" #include "scribusstructs.h" #include "text/nlsconfig.h" #include "util.h" #include "util_formats.h" bool DocumentChecker::checkDocument(ScribusDoc *currDoc) { PageItem* currItem; QString chstr; struct checkerPrefs checkerSettings; checkerSettings.ignoreErrors = currDoc->checkerProfiles[currDoc->curCheckProfile].ignoreErrors; checkerSettings.autoCheck = currDoc->checkerProfiles[currDoc->curCheckProfile].autoCheck; checkerSettings.checkGlyphs = currDoc->checkerProfiles[currDoc->curCheckProfile].checkGlyphs; checkerSettings.checkOrphans = currDoc->checkerProfiles[currDoc->curCheckProfile].checkOrphans; checkerSettings.checkOverflow = currDoc->checkerProfiles[currDoc->curCheckProfile].checkOverflow; checkerSettings.checkPictures = currDoc->checkerProfiles[currDoc->curCheckProfile].checkPictures; checkerSettings.checkResolution = currDoc->checkerProfiles[currDoc->curCheckProfile].checkResolution; checkerSettings.checkTransparency = currDoc->checkerProfiles[currDoc->curCheckProfile].checkTransparency; checkerSettings.minResolution = currDoc->checkerProfiles[currDoc->curCheckProfile].minResolution; checkerSettings.maxResolution = currDoc->checkerProfiles[currDoc->curCheckProfile].maxResolution; checkerSettings.checkAnnotations = currDoc->checkerProfiles[currDoc->curCheckProfile].checkAnnotations; checkerSettings.checkRasterPDF = currDoc->checkerProfiles[currDoc->curCheckProfile].checkRasterPDF; checkerSettings.checkForGIF = currDoc->checkerProfiles[currDoc->curCheckProfile].checkForGIF; checkerSettings.ignoreOffLayers = currDoc->checkerProfiles[currDoc->curCheckProfile].ignoreOffLayers; checkerSettings.checkOffConflictLayers = currDoc->checkerProfiles[currDoc->curCheckProfile].checkOffConflictLayers; currDoc->docItemErrors.clear(); currDoc->masterItemErrors.clear(); currDoc->docLayerErrors.clear(); errorCodes itemError; errorCodes layerError; int Lnr; ScLayer ll; ll.LNr = 0; Lnr = 0; uint layerCount= currDoc->layerCount(); for (uint la = 0; la < layerCount; ++la) { layerError.clear(); currDoc->Layers.levelToLayer(ll, Lnr); if ((ll.isViewable != ll.isPrintable) && (checkerSettings.checkOffConflictLayers)) layerError.insert(OffConflictLayers, 0); if ((!ll.isViewable) && (checkerSettings.ignoreOffLayers)) continue; if ((!ll.isPrintable) && (checkerSettings.ignoreOffLayers)) continue; if ((ll.transparency != 1.0) && (checkerSettings.checkTransparency)) layerError.insert(Transparency, 0); if ((ll.blendMode != 0) && (checkerSettings.checkTransparency)) layerError.insert(BlendMode, 1); Lnr++; if (layerError.count() != 0) currDoc->docLayerErrors.insert(ll.LNr, layerError); } for (int d = 0; d < currDoc->MasterItems.count(); ++d) { currItem = currDoc->MasterItems.at(d); if (!currItem->printEnabled()) continue; if (!(currDoc->layerPrintable(currItem->LayerNr)) && (checkerSettings.ignoreOffLayers)) continue; itemError.clear(); if (((currItem->isAnnotation()) || (currItem->isBookmark)) && (checkerSettings.checkAnnotations)) itemError.insert(PDFAnnotField, 0); if (((currItem->fillTransparency() != 0.0) || (currItem->lineTransparency() != 0.0) || (currItem->fillBlendmode() != 0) || (currItem->lineBlendmode() != 0)) && (checkerSettings.checkTransparency)) itemError.insert(Transparency, 0); if ((currItem->GrType != 0) && (checkerSettings.checkTransparency)) { QList colorStops = currItem->fill_gradient.colorStops(); for( int offset = 0 ; offset < colorStops.count() ; offset++ ) { if (colorStops[offset]->opacity != 1.0) { itemError.insert(Transparency, 0); break; } } } if ((currItem->OwnPage == -1) && (checkerSettings.checkOrphans)) itemError.insert(ObjectNotOnPage, 0); if (currItem->asImageFrame()) { if ((!currItem->PictureIsAvailable) && (checkerSettings.checkPictures)) itemError.insert(MissingImage, 0); else { if (((qRound(72.0 / currItem->imageXScale()) < checkerSettings.minResolution) || (qRound(72.0 / currItem->imageYScale()) < checkerSettings.minResolution)) && (currItem->isRaster) && (checkerSettings.checkResolution)) itemError.insert(ImageDPITooLow, 0); if (((qRound(72.0 / currItem->imageXScale()) > checkerSettings.maxResolution) || (qRound(72.0 / currItem->imageYScale()) > checkerSettings.maxResolution)) && (currItem->isRaster) && (checkerSettings.checkResolution)) itemError.insert(ImageDPITooHigh, 0); QFileInfo fi = QFileInfo(currItem->Pfile); QString ext = fi.suffix().toLower(); if (extensionIndicatesPDF(ext) && (checkerSettings.checkRasterPDF)) itemError.insert(PlacedPDF, 0); if ((ext == "gif") && (checkerSettings.checkForGIF)) itemError.insert(ImageIsGIF, 0); } } if ((currItem->asTextFrame()) || (currItem->asPathText())) { #ifndef NLS_PROTO if ( currItem->frameOverflows() && (checkerSettings.checkOverflow) && (!((currItem->isAnnotation()) && ((currItem->annotation().Type() == 5) || (currItem->annotation().Type() == 6))))) itemError.insert(TextOverflow, 0); if (currItem->isAnnotation()) { ScFace::FontFormat fformat = currItem->itemText.defaultStyle().charStyle().font().format(); if (!(fformat == ScFace::SFNT || fformat == ScFace::TTCF)) itemError.insert(WrongFontInAnnotation, 0); } for (int e = currItem->firstInFrame(); e <= currItem->lastInFrame(); ++e) { uint chr = currItem->itemText.text(e).unicode(); if ((chr == 13) || (chr == 32) || (chr == 29) || (chr == 28) || (chr == 27) || (chr == 26) || (chr == 25)) continue; if ((currItem->itemText.charStyle(e).effects() & ScStyle_SmallCaps) || (currItem->itemText.charStyle(e).effects() & ScStyle_AllCaps)) { chstr = currItem->itemText.text(e); if (chstr.toUpper() != currItem->itemText.text(e)) chstr = chstr.toUpper(); chr = chstr[0].unicode(); } if (chr == 9) { for (int t1 = 0; t1 < currItem->itemText.paragraphStyle(e).tabValues().count(); t1++) { if (currItem->itemText.paragraphStyle(e).tabValues()[t1].tabFillChar.isNull()) continue; chstr = QString(currItem->itemText.paragraphStyle(e).tabValues()[t1].tabFillChar); if ((currItem->itemText.charStyle(e).effects() & ScStyle_SmallCaps) || (currItem->itemText.charStyle(e).effects() & ScStyle_AllCaps)) { if (chstr.toUpper() != QString(currItem->itemText.paragraphStyle(e).tabValues()[t1].tabFillChar)) chstr = chstr.toUpper(); } chr = chstr[0].unicode(); if ((!currItem->itemText.charStyle(e).font().canRender(chr)) && (checkerSettings.checkGlyphs)) itemError.insert(MissingGlyph, 0); } for (int t1 = 0; t1 < currItem->itemText.defaultStyle().tabValues().count(); t1++) { if (currItem->itemText.defaultStyle().tabValues()[t1].tabFillChar.isNull()) continue; chstr = QString(currItem->itemText.defaultStyle().tabValues()[t1].tabFillChar); if ((currItem->itemText.charStyle(e).effects() & ScStyle_SmallCaps) || (currItem->itemText.charStyle(e).effects() & ScStyle_AllCaps)) { if (chstr.toUpper() != QString(currItem->itemText.defaultStyle().tabValues()[t1].tabFillChar)) chstr = chstr.toUpper(); } chr = chstr[0].unicode(); if ((!currItem->itemText.charStyle(e).font().canRender(chr)) && (checkerSettings.checkGlyphs)) itemError.insert(MissingGlyph, 0); } continue; } if ((chr == 30) || (chr == 23)) { for (int numco = 0x30; numco < 0x3A; ++numco) { if ((!currItem->itemText.charStyle(e).font().canRender(numco)) && (checkerSettings.checkGlyphs)) itemError.insert(MissingGlyph, 0); } continue; } if ((!currItem->itemText.charStyle(e).font().canRender(chr)) && (checkerSettings.checkGlyphs)) itemError.insert(MissingGlyph, 0); } #endif } if (itemError.count() != 0) currDoc->masterItemErrors.insert(currItem->ItemNr, itemError); } for (int d = 0; d < currDoc->DocItems.count(); ++d) { currItem = currDoc->DocItems.at(d); if (!currItem->printEnabled()) continue; if (!(currDoc->layerPrintable(currItem->LayerNr)) && (checkerSettings.ignoreOffLayers)) continue; itemError.clear(); if (((currItem->fillTransparency() != 0.0) || (currItem->lineTransparency() != 0.0) || (currItem->fillBlendmode() != 0) || (currItem->lineBlendmode() != 0)) && (checkerSettings.checkTransparency)) itemError.insert(Transparency, 0); if ((currItem->GrType != 0) && (checkerSettings.checkTransparency)) { QList colorStops = currItem->fill_gradient.colorStops(); for( int offset = 0 ; offset < colorStops.count() ; offset++ ) { if (colorStops[offset]->opacity != 1.0) { itemError.insert(Transparency, 0); break; } } } if (((currItem->isAnnotation()) || (currItem->isBookmark)) && (checkerSettings.checkAnnotations)) itemError.insert(PDFAnnotField, 0); if ((currItem->OwnPage == -1) && (checkerSettings.checkOrphans)) itemError.insert(ObjectNotOnPage, 0); if (currItem->asImageFrame()) { if ((!currItem->PictureIsAvailable) && (checkerSettings.checkPictures)) itemError.insert(MissingImage, 0); else { if (((qRound(72.0 / currItem->imageYScale()) < checkerSettings.minResolution) || (qRound(72.0 / currItem->imageYScale()) < checkerSettings.minResolution)) && (currItem->isRaster) && (checkerSettings.checkResolution)) itemError.insert(ImageDPITooLow, 0); if (((qRound(72.0 / currItem->imageXScale()) > checkerSettings.maxResolution) || (qRound(72.0 / currItem->imageYScale()) > checkerSettings.maxResolution)) && (currItem->isRaster) && (checkerSettings.checkResolution)) itemError.insert(ImageDPITooHigh, 0); QFileInfo fi = QFileInfo(currItem->Pfile); QString ext = fi.suffix().toLower(); if (extensionIndicatesPDF(ext) && (checkerSettings.checkRasterPDF)) itemError.insert(PlacedPDF, 0); if ((ext == "gif") && (checkerSettings.checkForGIF)) itemError.insert(ImageIsGIF, 0); } } if ((currItem->asTextFrame()) || (currItem->asPathText())) { #ifndef NLS_PROTO if ( currItem->frameOverflows() && (checkerSettings.checkOverflow) && (!((currItem->isAnnotation()) && ((currItem->annotation().Type() == 5) || (currItem->annotation().Type() == 6))))) itemError.insert(TextOverflow, 0); if (currItem->isAnnotation()) { ScFace::FontFormat fformat = currItem->itemText.defaultStyle().charStyle().font().format(); if (!(fformat == ScFace::SFNT || fformat == ScFace::TTCF)) itemError.insert(WrongFontInAnnotation, 0); } for (int e = currItem->firstInFrame(); e <= currItem->lastInFrame(); ++e) { uint chr = currItem->itemText.text(e).unicode(); if ((chr == 13) || (chr == 32) || (chr == 29) || (chr == 28) || (chr == 27) || (chr == 26) || (chr == 25)) continue; if ((currItem->itemText.charStyle(e).effects() & ScStyle_SmallCaps) || (currItem->itemText.charStyle(e).effects() & ScStyle_AllCaps)) { chstr = currItem->itemText.text(e,1); if (chstr.toUpper() != currItem->itemText.text(e,1)) chstr = chstr.toUpper(); chr = chstr[0].unicode(); } if (chr == 9) { for (int t1 = 0; t1 < currItem->itemText.paragraphStyle(e).tabValues().count(); t1++) { if (currItem->itemText.paragraphStyle(e).tabValues()[t1].tabFillChar.isNull()) continue; chstr = QString(currItem->itemText.paragraphStyle(e).tabValues()[t1].tabFillChar); if ((currItem->itemText.charStyle(e).effects() & ScStyle_SmallCaps) || (currItem->itemText.charStyle(e).effects() & ScStyle_AllCaps)) { if (chstr.toUpper() != QString(currItem->itemText.paragraphStyle(e).tabValues()[t1].tabFillChar)) chstr = chstr.toUpper(); } chr = chstr[0].unicode(); if ((!currItem->itemText.charStyle(e).font().canRender(chr)) && (checkerSettings.checkGlyphs)) itemError.insert(MissingGlyph, 0); } for (int t1 = 0; t1 < currItem->itemText.defaultStyle().tabValues().count(); t1++) { if (currItem->itemText.defaultStyle().tabValues()[t1].tabFillChar.isNull()) continue; chstr = QString(currItem->itemText.defaultStyle().tabValues()[t1].tabFillChar); if ((currItem->itemText.charStyle(e).effects() & ScStyle_SmallCaps) || (currItem->itemText.charStyle(e).effects() & ScStyle_AllCaps)) { if (chstr.toUpper() != QString(currItem->itemText.defaultStyle().tabValues()[t1].tabFillChar)) chstr = chstr.toUpper(); } chr = chstr[0].unicode(); if ((!currItem->itemText.charStyle(e).font().canRender(chr)) && (checkerSettings.checkGlyphs)) itemError.insert(MissingGlyph, 0); } continue; } if ((chr == 30) || (chr == 23)) { for (uint numco = 0x30; numco < 0x3A; ++numco) { if ((!currItem->itemText.charStyle(e).font().canRender(numco)) && (checkerSettings.checkGlyphs)) itemError.insert(MissingGlyph, 0); } continue; } if ((!currItem->itemText.charStyle(e).font().canRender(chr)) && (checkerSettings.checkGlyphs)) itemError.insert(MissingGlyph, 0); } #endif } if (itemError.count() != 0) currDoc->docItemErrors.insert(currItem->ItemNr, itemError); } return ((currDoc->docItemErrors.count() != 0) || (currDoc->masterItemErrors.count() != 0) || (currDoc->docLayerErrors.count() != 0)); }