/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "impedit.hxx" #include #include #include #include "editdbg.hxx" #include #include #if defined( DBG_UTIL ) || ( OSL_DEBUG_LEVEL > 1 ) OString DbgOutItem(const SfxItemPool& rPool, const SfxPoolItem& rItem) { OStringBuffer aDebStr; switch ( rItem.Which() ) { case EE_PARA_WRITINGDIR: aDebStr.append("WritingDir="); aDebStr.append(static_cast(static_cast(rItem).GetValue())); break; case EE_PARA_OUTLLRSPACE: case EE_PARA_LRSPACE: aDebStr.append("FI="); aDebStr.append(static_cast(static_cast(rItem).GetTextFirstLineOfst())); aDebStr.append(", LI="); aDebStr.append(static_cast(static_cast(rItem).GetTextLeft())); aDebStr.append(", RI="); aDebStr.append(static_cast(static_cast(rItem).GetRight())); break; case EE_PARA_NUMBULLET: aDebStr.append("NumItem "); for ( sal_uInt16 nLevel = 0; nLevel < 3; nLevel++ ) { aDebStr.append("Level"); aDebStr.append(static_cast(nLevel)); aDebStr.append('='); const SvxNumberFormat* pFmt = static_cast(rItem).GetNumRule()->Get( nLevel ); if ( pFmt ) { aDebStr.append('('); aDebStr.append(pFmt->GetFirstLineOffset()); aDebStr.append(','); aDebStr.append(pFmt->GetAbsLSpace()); aDebStr.append(','); if ( pFmt->GetNumberingType() == SVX_NUM_BITMAP ) aDebStr.append("Bitmap"); else if( pFmt->GetNumberingType() != SVX_NUM_CHAR_SPECIAL ) aDebStr.append("Number"); else { aDebStr.append("Char=["); aDebStr.append(static_cast(pFmt->GetBulletChar())); aDebStr.append(']'); } aDebStr.append(") "); } } break; case EE_PARA_BULLETSTATE: aDebStr.append("ShowBullet="); aDebStr.append(static_cast(static_cast(rItem).GetValue())); break; case EE_PARA_HYPHENATE: aDebStr.append("Hyphenate="); aDebStr.append(static_cast(static_cast(rItem).GetValue())); break; case EE_PARA_OUTLLEVEL: aDebStr.append("Level="); aDebStr.append(static_cast(static_cast(rItem).GetValue())); break; case EE_PARA_ULSPACE: aDebStr.append("SB="); aDebStr.append(static_cast(static_cast(rItem).GetUpper())); aDebStr.append(", SA="); aDebStr.append(static_cast(static_cast(rItem).GetLower())); break; case EE_PARA_SBL: aDebStr.append("SBL="); if ( static_cast(rItem).GetLineSpaceRule() == SvxLineSpaceRule::Min ) { aDebStr.append("Min: "); aDebStr.append(static_cast(static_cast(rItem).GetInterLineSpace())); } else if ( static_cast(rItem).GetInterLineSpaceRule() == SvxInterLineSpaceRule::Prop ) { aDebStr.append("Prop: "); aDebStr.append(static_cast(static_cast(rItem).GetPropLineSpace())); } else aDebStr.append("Unsupported Type!"); break; case EE_PARA_JUST: aDebStr.append("SvxAdust="); aDebStr.append(static_cast(static_cast(rItem).GetAdjust())); break; case EE_PARA_TABS: { aDebStr.append("Tabs: "); const SvxTabStopItem& rTabs = static_cast(rItem); aDebStr.append(static_cast(rTabs.Count())); if ( rTabs.Count() ) { aDebStr.append("( "); for (sal_uInt16 i = 0; i < rTabs.Count(); ++i) { const SvxTabStop& rTab = rTabs[i]; aDebStr.append(rTab.GetTabPos()); aDebStr.append(' '); } aDebStr.append(')'); } } break; case EE_CHAR_LANGUAGE: case EE_CHAR_LANGUAGE_CJK: case EE_CHAR_LANGUAGE_CTL: aDebStr.append("Language="); aDebStr.append(static_cast(static_cast(static_cast(rItem).GetLanguage()))); break; case EE_CHAR_COLOR: { aDebStr.append("Color= "); Color aColor( static_cast(rItem).GetValue() ); aDebStr.append(static_cast(aColor.GetRed())); aDebStr.append(", "); aDebStr.append(static_cast(aColor.GetGreen())); aDebStr.append(", "); aDebStr.append(static_cast(aColor.GetBlue())); } break; case EE_CHAR_BKGCOLOR: { aDebStr.append("FillColor= "); Color aColor( static_cast(rItem).GetValue() ); aDebStr.append(static_cast(aColor.GetRed())); aDebStr.append(", "); aDebStr.append(static_cast(aColor.GetGreen())); aDebStr.append(", "); aDebStr.append(static_cast(aColor.GetBlue())); } break; case EE_CHAR_FONTINFO: case EE_CHAR_FONTINFO_CJK: case EE_CHAR_FONTINFO_CTL: { aDebStr.append("Font="); aDebStr.append(OUStringToOString(static_cast(rItem).GetFamilyName(), RTL_TEXTENCODING_ASCII_US)); aDebStr.append(" (CharSet: "); aDebStr.append(static_cast(static_cast(rItem).GetCharSet())); aDebStr.append(')'); } break; case EE_CHAR_FONTHEIGHT: case EE_CHAR_FONTHEIGHT_CJK: case EE_CHAR_FONTHEIGHT_CTL: { aDebStr.append("Groesse="); aDebStr.append(static_cast(static_cast(rItem).GetHeight())); Size aSz( 0, static_cast(rItem).GetHeight() ); MapUnit eUnit = rPool.GetMetric( rItem.Which() ); MapMode aItemMapMode(eUnit); MapMode aPntMap( MapUnit::MapPoint ); aSz = OutputDevice::LogicToLogic( aSz, aItemMapMode, aPntMap ); aDebStr.append(" Points="); aDebStr.append(static_cast(aSz.Height())); } break; case EE_CHAR_FONTWIDTH: { aDebStr.append("Breite="); aDebStr.append(static_cast(static_cast(rItem).GetValue())); aDebStr.append('%'); } break; case EE_CHAR_WEIGHT: case EE_CHAR_WEIGHT_CJK: case EE_CHAR_WEIGHT_CTL: aDebStr.append("FontWeight="); aDebStr.append(static_cast(static_cast(rItem).GetWeight())); break; case EE_CHAR_UNDERLINE: aDebStr.append("FontUnderline="); aDebStr.append(static_cast(static_cast(rItem).GetLineStyle())); break; case EE_CHAR_OVERLINE: aDebStr.append("FontOverline="); aDebStr.append(static_cast(static_cast(rItem).GetLineStyle())); break; case EE_CHAR_EMPHASISMARK: aDebStr.append("FontUnderline="); aDebStr.append(static_cast(static_cast(rItem).GetEmphasisMark())); break; case EE_CHAR_RELIEF: aDebStr.append("FontRelief="); aDebStr.append(static_cast(static_cast(rItem).GetValue())); break; case EE_CHAR_STRIKEOUT: aDebStr.append("FontStrikeout="); aDebStr.append(static_cast(static_cast(rItem).GetStrikeout())); break; case EE_CHAR_ITALIC: case EE_CHAR_ITALIC_CJK: case EE_CHAR_ITALIC_CTL: aDebStr.append("FontPosture="); aDebStr.append(static_cast(static_cast(rItem).GetPosture())); break; case EE_CHAR_OUTLINE: aDebStr.append("FontOutline="); aDebStr.append(static_cast(static_cast(rItem).GetValue())); break; case EE_CHAR_SHADOW: aDebStr.append("FontShadowed="); aDebStr.append(static_cast(static_cast(rItem).GetValue())); break; case EE_CHAR_ESCAPEMENT: aDebStr.append("Escape="); aDebStr.append(static_cast(static_cast(rItem).GetEsc())); aDebStr.append(", "); aDebStr.append(static_cast(static_cast(rItem).GetProportionalHeight())); break; case EE_CHAR_PAIRKERNING: aDebStr.append("PairKerning="); aDebStr.append(static_cast(static_cast(rItem).GetValue())); break; case EE_CHAR_KERNING: { aDebStr.append("Kerning="); aDebStr.append(static_cast(static_cast(rItem).GetValue())); Size aSz( 0, static_cast(static_cast(rItem).GetValue()) ); MapUnit eUnit = rPool.GetMetric( rItem.Which() ); MapMode aItemMapMode(eUnit); MapMode aPntMap( MapUnit::MapPoint ); aSz = OutputDevice::LogicToLogic( aSz, aItemMapMode, aPntMap ); aDebStr.append(" Points="); aDebStr.append(static_cast(aSz.Height())); } break; case EE_CHAR_WLM: aDebStr.append("WordLineMode="); aDebStr.append(static_cast(static_cast(rItem).GetValue())); break; case EE_CHAR_XMLATTRIBS: aDebStr.append("XMLAttribs=..."); break; } return aDebStr.makeStringAndClear(); } void DbgOutItemSet( FILE* fp, const SfxItemSet& rSet, bool bSearchInParent, bool bShowALL ) { for ( sal_uInt16 nWhich = EE_PARA_START; nWhich <= EE_CHAR_END; nWhich++ ) { fprintf( fp, "\nWhich: %i\t", nWhich ); if ( rSet.GetItemState( nWhich, bSearchInParent ) == SfxItemState::DEFAULT ) fprintf( fp, "ITEM_OFF " ); else if ( rSet.GetItemState( nWhich, bSearchInParent ) == SfxItemState::DONTCARE ) fprintf( fp, "ITEM_DC " ); else if ( rSet.GetItemState( nWhich, bSearchInParent ) == SfxItemState::SET ) fprintf( fp, "ITEM_ON *" ); if ( !bShowALL && ( rSet.GetItemState( nWhich, bSearchInParent ) != SfxItemState::SET ) ) continue; const SfxPoolItem& rItem = rSet.Get( nWhich, bSearchInParent ); OString aDebStr = DbgOutItem( *rSet.GetPool(), rItem ); fprintf( fp, "%s", aDebStr.getStr() ); } } void EditDbg::ShowEditEngineData( EditEngine* pEE, bool bInfoBox ) { #if defined UNX FILE* fp = fopen( "/tmp/debug.log", "w" ); #else FILE* fp = fopen( "d:\\debug.log", "w" ); #endif if ( fp == nullptr ) { OSL_FAIL( "Log file could not be created!" ); return; } const SfxItemPool& rPool = *pEE->GetEmptyItemSet().GetPool(); fprintf( fp, "================================================================================" ); fprintf( fp, "\n================== Document ================================================" ); fprintf( fp, "\n================================================================================" ); for ( sal_Int32 nPortion = 0; nPortion < pEE->pImpEditEngine->GetParaPortions().Count(); nPortion++) { ParaPortion* pPPortion = pEE->pImpEditEngine->GetParaPortions()[nPortion]; fprintf( fp, "\nParagraph %" SAL_PRIdINT32 ": Length = %" SAL_PRIdINT32 ", Invalid = %i\nText = '%s'", nPortion, pPPortion->GetNode()->Len(), pPPortion->IsInvalid(), OUStringToOString(pPPortion->GetNode()->GetString(), RTL_TEXTENCODING_UTF8).getStr() ); fprintf( fp, "\nVorlage:" ); SfxStyleSheet* pStyle = pPPortion->GetNode()->GetStyleSheet(); if ( pStyle ) fprintf( fp, " %s", OUStringToOString( pStyle->GetName(), RTL_TEXTENCODING_UTF8).getStr() ); fprintf( fp, "\nParagraph attribute:" ); DbgOutItemSet( fp, pPPortion->GetNode()->GetContentAttribs().GetItems(), false, false ); fprintf( fp, "\nCharacter attribute:" ); bool bZeroAttr = false; for ( sal_Int32 z = 0; z < pPPortion->GetNode()->GetCharAttribs().Count(); ++z ) { const std::unique_ptr& rAttr = pPPortion->GetNode()->GetCharAttribs().GetAttribs()[z]; OStringBuffer aCharAttribs; aCharAttribs.append("\nA"); aCharAttribs.append(nPortion); aCharAttribs.append(": "); aCharAttribs.append(static_cast(rAttr->GetItem()->Which())); aCharAttribs.append('\t'); aCharAttribs.append(rAttr->GetStart()); aCharAttribs.append('\t'); aCharAttribs.append(rAttr->GetEnd()); if ( rAttr->IsEmpty() ) bZeroAttr = true; fprintf(fp, "%s => ", aCharAttribs.getStr()); OString aDebStr = DbgOutItem( rPool, *rAttr->GetItem() ); fprintf( fp, "%s", aDebStr.getStr() ); } if ( bZeroAttr ) fprintf( fp, "\nNULL-Attribute!" ); const sal_Int32 nTextPortions = pPPortion->GetTextPortions().Count(); OStringBuffer aPortionStr("\nText portions: #"); aPortionStr.append(nTextPortions); aPortionStr.append(" \nA"); aPortionStr.append(nPortion); aPortionStr.append(": Paragraph Length = "); aPortionStr.append(pPPortion->GetNode()->Len()); aPortionStr.append("\nA"); aPortionStr.append(nPortion); aPortionStr.append(": "); sal_Int32 n = 0; for ( sal_Int32 z = 0; z < nTextPortions; ++z ) { TextPortion& rPortion = pPPortion->GetTextPortions()[z]; aPortionStr.append(' '); aPortionStr.append(rPortion.GetLen()); aPortionStr.append('('); aPortionStr.append(static_cast(rPortion.GetSize().Width())); aPortionStr.append(')'); aPortionStr.append('['); aPortionStr.append(static_cast(rPortion.GetKind())); aPortionStr.append(']'); aPortionStr.append(';'); n += rPortion.GetLen(); } aPortionStr.append("\nA"); aPortionStr.append(nPortion); aPortionStr.append(": Total length: "); aPortionStr.append(n); if ( pPPortion->GetNode()->Len() != n ) aPortionStr.append(" => Error !!!"); fprintf(fp, "%s", aPortionStr.getStr()); fprintf( fp, "\n\nLines:" ); // First the content ... for ( sal_Int32 nLine = 0; nLine < pPPortion->GetLines().Count(); nLine++ ) { EditLine& rLine = pPPortion->GetLines()[nLine]; OString aLine(OUStringToOString(pPPortion->GetNode()->Copy(rLine.GetStart(), rLine.GetEnd() - rLine.GetStart()), RTL_TEXTENCODING_ASCII_US)); fprintf( fp, "\nLine %" SAL_PRIdINT32 "\t>%s<", nLine, aLine.getStr() ); } // then the internal data ... for ( sal_Int32 nLine = 0; nLine < pPPortion->GetLines().Count(); nLine++ ) { EditLine& rLine = pPPortion->GetLines()[nLine]; fprintf( fp, "\nLine %" SAL_PRIdINT32 ":\tStart: %" SAL_PRIdINT32 ",\tEnd: %" SAL_PRIdINT32, nLine, rLine.GetStart(), rLine.GetEnd() ); fprintf( fp, "\t\tPortions: %" SAL_PRIdINT32 " - %" SAL_PRIdINT32 ".\tHight: %i, Ascent=%i", rLine.GetStartPortion(), rLine.GetEndPortion(), rLine.GetHeight(), rLine.GetMaxAscent() ); } fprintf( fp, "\n-----------------------------------------------------------------------------" ); } if ( pEE->pImpEditEngine->GetStyleSheetPool() ) { sal_uInt16 nStyles = pEE->pImpEditEngine->GetStyleSheetPool() ? pEE->pImpEditEngine->GetStyleSheetPool()->Count() : 0; fprintf( fp, "\n\n================================================================================" ); fprintf( fp, "\n================== Stylesheets =============================================" ); fprintf( fp, "\n================================================================================" ); fprintf( fp, "\n#Template: %" SAL_PRIuUINT32 "\n", sal_uInt32(nStyles) ); SfxStyleSheetIterator aIter( pEE->pImpEditEngine->GetStyleSheetPool(), SfxStyleFamily::All ); SfxStyleSheetBase* pStyle = aIter.First(); while ( pStyle ) { fprintf( fp, "\nTemplate: %s", OUStringToOString( pStyle->GetName(), RTL_TEXTENCODING_ASCII_US ).getStr() ); fprintf( fp, "\nParent: %s", OUStringToOString( pStyle->GetParent(), RTL_TEXTENCODING_ASCII_US ).getStr() ); fprintf( fp, "\nFollow: %s", OUStringToOString( pStyle->GetFollow(), RTL_TEXTENCODING_ASCII_US ).getStr() ); DbgOutItemSet( fp, pStyle->GetItemSet(), false, false ); fprintf( fp, "\n----------------------------------" ); pStyle = aIter.Next(); } } fprintf( fp, "\n\n================================================================================" ); fprintf( fp, "\n================== Defaults ================================================" ); fprintf( fp, "\n================================================================================" ); DbgOutItemSet( fp, pEE->pImpEditEngine->GetEmptyItemSet(), true, true ); fprintf( fp, "\n\n================================================================================" ); fprintf( fp, "\n================== EditEngine & Views ======================================" ); fprintf( fp, "\n================================================================================" ); fprintf( fp, "\nControl: %x", unsigned( pEE->GetControlWord() ) ); fprintf( fp, "\nRefMapMode: %i", int( pEE->pImpEditEngine->pRefDev->GetMapMode().GetMapUnit() ) ); fprintf( fp, "\nPaperSize: %li x %li", pEE->GetPaperSize().Width(), pEE->GetPaperSize().Height() ); fprintf( fp, "\nMaxAutoPaperSize: %li x %li", pEE->GetMaxAutoPaperSize().Width(), pEE->GetMaxAutoPaperSize().Height() ); fprintf( fp, "\nMinAutoPaperSize: %li x %li", pEE->GetMinAutoPaperSize().Width(), pEE->GetMinAutoPaperSize().Height() ); fprintf( fp, "\nUpdate: %i", pEE->GetUpdateMode() ); fprintf( fp, "\nNumber of Views: %" SAL_PRI_SIZET "i", pEE->GetViewCount() ); for ( size_t nView = 0; nView < pEE->GetViewCount(); nView++ ) { EditView* pV = pEE->GetView( nView ); DBG_ASSERT( pV, "View not found!" ); fprintf( fp, "\nView %zu: Focus=%i", nView, pV->GetWindow()->HasFocus() ); tools::Rectangle aR( pV->GetOutputArea() ); fprintf( fp, "\n OutputArea: nX=%li, nY=%li, dX=%li, dY=%li, MapMode = %i", aR.TopLeft().X(), aR.TopLeft().Y(), aR.GetSize().Width(), aR.GetSize().Height() , int( pV->GetWindow()->GetMapMode().GetMapUnit() ) ); aR = pV->GetVisArea(); fprintf( fp, "\n VisArea: nX=%li, nY=%li, dX=%li, dY=%li", aR.TopLeft().X(), aR.TopLeft().Y(), aR.GetSize().Width(), aR.GetSize().Height() ); ESelection aSel = pV->GetSelection(); fprintf( fp, "\n Selection: Start=%" SAL_PRIdINT32 ",%" SAL_PRIdINT32 ", End=%" SAL_PRIdINT32 ",%" SAL_PRIdINT32, aSel.nStartPara, aSel.nStartPos, aSel.nEndPara, aSel.nEndPos ); } if ( pEE->GetActiveView() ) { fprintf( fp, "\n\n================================================================================" ); fprintf( fp, "\n================== Current View ===========================================" ); fprintf( fp, "\n================================================================================" ); DbgOutItemSet( fp, pEE->GetActiveView()->GetAttribs(), true, false ); } fclose( fp ); if ( bInfoBox ) { std::unique_ptr xInfoBox(Application::CreateMessageDialog(nullptr, VclMessageType::Info, VclButtonsType::Ok, "D:\\DEBUG.LOG !" )); xInfoBox->run(); } } #endif #if OSL_DEBUG_LEVEL > 0 bool ParaPortion::DbgCheckTextPortions(ParaPortion const& rPara) { // check, if Portion length ok: sal_uInt16 nXLen = 0; for (sal_Int32 nPortion = 0; nPortion < rPara.aTextPortionList.Count(); nPortion++) { nXLen = nXLen + rPara.aTextPortionList[nPortion].GetLen(); } return nXLen == rPara.pNode->Len(); } #endif #if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG void CheckOrderedList(const CharAttribList::AttribsType& rAttribs) { sal_Int32 nPrev = 0; for (const std::unique_ptr& rAttr : rAttribs) { sal_Int32 const nCur = rAttr->GetStart(); assert(nCur >= nPrev); nPrev = nCur; } } #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */