Bool TryCutBlockOnHorizontal (BLOCK *p) { int iColumn; int iZeroEnd; Bool bNotSpace; int iBestPointSizeBreakingColumn; int nPointSizeDifference; int nBestPointSizeDifference = 0; /* To avoid warning on MPW C/C++ */ BLOCK *q, *r; # ifdef LT_DEBUG if (p -> pHorzHystogram == NULL) ErrorInternal ("pHorzHystogram not builded in TryCutBlockOnHorizontal"); # endif nHystColumnWidth = 1; nHystColumns = p -> Rect.yBottom - p -> Rect.yTop + 1; memcpy (pHystogram, p -> pHorzHystogram, nHystColumns * sizeof (int)); # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 4) if(!LDPUMA_Skip(hBlocksBreaking)) LT_GraphicsHystogramOutput ("Hystogram for horizontal breaking"); # endif bNotSpace = FALSE; for (iColumn = 0; iColumn < nHystColumns; iColumn++) { if (pHystogram [iColumn] != 0) { bNotSpace = TRUE; continue; } if (! bNotSpace) continue; for (iZeroEnd = iColumn + 1; iZeroEnd < nHystColumns && pHystogram [iZeroEnd] == 0; iZeroEnd++) { } if (iZeroEnd == nHystColumns) break; if (HorizontalBreakingCondition (p, iColumn, iZeroEnd - 1) && BlockBreakOnHorizontal (p, NULL, NULL, iColumn + p -> Rect.yTop)) { return (TRUE); } iColumn = iZeroEnd; } /* * Analysis with font accounting */ if (! bOptionPointSizeAnalysis) return (FALSE); BlockBuild_HystHorzHeightesSum (p); HystogramMakeIntegral (pHystInt1, pHystogram, nHystColumns); HystogramMakeIntegral (pHystInt2, pHystHorzHeightesSum, nHystColumns); iBestPointSizeBreakingColumn = 0; for (iColumn = 0; iColumn < nHystColumns; iColumn++) { int nAverageHeightBefore; int nAverageHeightAfter; if (pHystogram [iColumn] != 0) continue; if (pHystInt1 [iColumn] == 0 || pHystInt1 [nHystColumns - 1] - pHystInt1 [iColumn] <= 20) { continue; } nAverageHeightBefore = pHystInt2 [iColumn] / pHystInt1 [iColumn]; nAverageHeightAfter = (pHystInt2 [nHystColumns - 1] - pHystInt2 [iColumn]) / (pHystInt1 [nHystColumns - 1] - pHystInt1 [iColumn]); if (nAverageHeightBefore == 0 || nAverageHeightAfter == 0) continue; if (! ((nAverageHeightBefore-1)*2 >= nAverageHeightAfter * ZagolovokBreakingCoeff || (nAverageHeightAfter-1)*2 >= nAverageHeightBefore * ZagolovokBreakingCoeff)) { continue; } nPointSizeDifference = MAX (nAverageHeightBefore * 1000 / nAverageHeightAfter, nAverageHeightAfter * 1000 / nAverageHeightBefore); if (iBestPointSizeBreakingColumn == 0 || nPointSizeDifference > nBestPointSizeDifference) { iBestPointSizeBreakingColumn = iColumn; nBestPointSizeDifference = nPointSizeDifference; } } iColumn = iBestPointSizeBreakingColumn; if (pHystInt1 [nHystColumns - 1] - pHystInt1 [iColumn] > 0 && iColumn <= (pHystInt2 [nHystColumns - 1] - pHystInt2 [iColumn]) / (pHystInt1 [nHystColumns - 1] - pHystInt1 [iColumn]) / 2) { /* Strange case: its possibly dots above letters */ return (FALSE); } if (BlockBreakOnHorizontal (p, &q, &r, iBestPointSizeBreakingColumn + p -> Rect.yTop)) { # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 3) if(!LDPUMA_Skip(hBlocksBreaking)) { pDebugBlock = q; LT_GraphicsBlockOutput2 ("Block was breaked using " "Horz PointSizeAnalysis"); pDebugBlock = r; LT_GraphicsBlockOutput2 ("Block was breaked using " "Horz PointSizeAnalysis"); LT_Getch (); LT_GraphicsClearScreen (); } # endif return (TRUE); } return (FALSE); }
static void ScreenOutput (const char *pTitle, void (*pProcUpdate) (int xLeft, int yTop, int nScaling)) { int nWidth = 3000; int nHeight = 3000; Bool bNeedUpdateScreen = TRUE; for (;;) { if (bNeedUpdateScreen) { (*pProcUpdate) (xCurrentLeft, yCurrentTop, nCurrentScaling); LT_GraphicsTitle (pTitle); } do { switch (LT_Getch ()) { case ' ': return; case KEY_LEFT: if (xCurrentLeft > 0) { xCurrentLeft -= SCREEN_WIDTH / STEPS * nCurrentScaling; bNeedUpdateScreen = TRUE; } break; case KEY_RIGHT: /* if (xCurrentLeft + SCREEN_WIDTH / STEPS * nCurrentScaling < nWidth) */ if (xCurrentLeft < nWidth) { xCurrentLeft += SCREEN_WIDTH / STEPS * nCurrentScaling; bNeedUpdateScreen = TRUE; } break; case KEY_UP: if (yCurrentTop > 0) { yCurrentTop -= SCREEN_HEIGHT / STEPS * nCurrentScaling; bNeedUpdateScreen = TRUE; } break; case KEY_DOWN: /* if (yCurrentTop + SCREEN_HEIGHT / STEPS * nCurrentScaling < nHeight) */ if (yCurrentTop < nHeight) { yCurrentTop += SCREEN_HEIGHT / STEPS * nCurrentScaling; bNeedUpdateScreen = TRUE; } break; case KEY_F1: if (nCurrentScaling != MIN_SCALING) { // yCurrentTop = 0; // xCurrentLeft = 0; nCurrentScaling /= 2; bNeedUpdateScreen = TRUE; } break; case KEY_F2: if (nCurrentScaling != MAX_SCALING) { // yCurrentTop = 0; // xCurrentLeft = 0; nCurrentScaling *= 2; bNeedUpdateScreen = TRUE; } break; case KEY_F10: # ifdef LT_DEBUG LT_DebugGraphicsLevel = 0; # endif # ifdef SE_DEBUG SE_DebugGraphicsLevel = 0; # endif return; default: bNeedUpdateScreen = FALSE; break; } } while (!bNeedUpdateScreen); } }
Bool TryCutBlockOnVertical (BLOCK *p, int bcr_cut, Bool32 SecondStage) { ROOT *pRoot; int iLeftColumn, iRightColumn; int iColumn; int nMaximum; int nLowLevel; int nSpaceWidth; int iSpace; int nHystSum; Bool bNotSpace; int iLeftLimit; int iRightLimit; int iBestPointSizeBreakingColumn; int nPointSizeDifference; int nBestPointSizeDifference = 0; /* To avoid warning on MPW C/C++ */ int nSum; int nAverage; int nColumns; BLOCK *q, *r; # ifdef LT_DEBUG if (p -> pHorzHystogram == NULL) ErrorInternal ("pHorzHystogram not builded in TryCutBlockOnVertical"); # endif nHystColumnWidth = p -> nStartColumnWidth; while (nHystColumnWidth >= p -> nConditionalMinColumnWidth) { /* Build vertical hystogram */ nHystColumns = (p -> Rect.xRight - p -> Rect.xLeft + 1) / nHystColumnWidth + 1; //memset (pHystogram, 0, nHystColumns * sizeof (int)); memset (pHystogram, 0, (nHystColumns + 1) * sizeof (int));// Piter 08.07.99 for (pRoot = p -> pRoots; pRoot != NULL; pRoot = pRoot -> u1.pNext) { iLeftColumn = (pRoot -> xColumn - p -> Rect.xLeft) / nHystColumnWidth; iRightColumn = (pRoot -> xColumn + pRoot -> nWidth - 1 - p -> Rect.xLeft) / nHystColumnWidth; pHystogram [iLeftColumn] ++; pHystogram [iRightColumn + 1] --; } nMaximum = 0; nHystSum = 0; for (iColumn = 0; iColumn < nHystColumns; iColumn++) { nHystSum += pHystogram [iColumn]; pHystogram [iColumn] = nHystSum; if (pHystogram [iColumn] > nMaximum) nMaximum = pHystogram [iColumn]; } nLowLevel = VERT_HYST_LOW_LEVEL (nMaximum); /* Rom */ if (SecondStage) { nSum = 0; for (iColumn = 0; iColumn < nHystColumns; iColumn++) { nSum += pHystogram [iColumn]; } if(nHystColumns!= 0) { nAverage = nSum/nHystColumns; } nSum = 0; nColumns = 0; for (iColumn = 0; iColumn < nHystColumns; iColumn++) { if(pHystogram [iColumn] > nAverage) { nSum += pHystogram [iColumn]; nColumns++; } } if(nColumns!= 0) { nAverage = nSum/nColumns; } for (iColumn = 0; iColumn < nHystColumns; iColumn++) { if(pHystogram [iColumn] < nAverage / 10) { pHystogram [iColumn] = 0; } } } /* Rom */ # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 4) if(!LDPUMA_Skip(hBlocksBreaking)) { pDebugBlock = p; // Piter 02-10-98 LT_GraphicsHystogramOutput ("Hystogram for vertical breaking"); } # endif bNotSpace = FALSE; for (iColumn = 0; iColumn < nHystColumns; iColumn++) { if (pHystogram [iColumn] == 0) { if (! bNotSpace) continue; if (nHystColumnWidth < p -> nUnconditionalMinColumnWidth && ! CorrectCondition (iColumn)) { continue; } nSpaceWidth = 0; for (iSpace = iColumn; iSpace < nHystColumns && pHystogram [iSpace] == 0; iSpace++) { nSpaceWidth += nHystColumnWidth; } if (iSpace == nHystColumns) break; if (BlockBreakOnVertical (p, NULL, NULL, iColumn * nHystColumnWidth + p -> Rect.xLeft, nSpaceWidth)) { return (TRUE); } iColumn += nSpaceWidth; } else { bNotSpace = TRUE; } } for (iColumn = 0; iColumn < nHystColumns; iColumn++) { if (pHystogram [iColumn] < nLowLevel) { nHystColumnWidth /= 2; break; } } if (iColumn == nHystColumns) break; } /* * Analysis with font accounting */ if (! (bOptionPointSizeAnalysis && bOptionBusinessCardsLayout)) return (FALSE); if (!bcr_cut) return (FALSE); // 940228 /* Build vertical hystogram */ if (nHystColumnWidth != 1) { nHystColumns = p -> Rect.xRight - p -> Rect.xLeft + 1; memset (pHystogram, 0, nHystColumns * sizeof (int)); for (pRoot = p -> pRoots; pRoot != NULL; pRoot = pRoot -> u1.pNext) { iLeftColumn = pRoot -> xColumn - p -> Rect.xLeft; iRightColumn = pRoot -> xColumn + pRoot -> nWidth - 1 - p -> Rect.xLeft; pHystogram [iLeftColumn] ++; pHystogram [iRightColumn + 1] --; } nHystSum = 0; for (iColumn = 0; iColumn < nHystColumns; iColumn++) { nHystSum += pHystogram [iColumn]; pHystogram [iColumn] = nHystSum; } } BlockBuild_HystVertHeightesSum (p); HystogramMakeIntegral (pHystInt1, pHystogram, nHystColumns); HystogramMakeIntegral (pHystInt2, pHystVertHeightesSum, nHystColumns); iLeftLimit = nHystColumns / 10; iRightLimit = nHystColumns - nHystColumns / 10; iBestPointSizeBreakingColumn = 0; for (iColumn = iLeftLimit; iColumn < iRightLimit; iColumn++) { int nAverageHeightBefore; int nAverageHeightAfter; if (pHystogram [iColumn] != 0) continue; if (pHystInt1 [iColumn] == 0 || pHystInt1 [nHystColumns - 1] - pHystInt1 [iColumn] == 0) { continue; } nAverageHeightBefore = pHystInt2 [iColumn] / pHystInt1 [iColumn]; nAverageHeightAfter = (pHystInt2 [nHystColumns - 1] - pHystInt2 [iColumn]) / (pHystInt1 [nHystColumns - 1] - pHystInt1 [iColumn]); if (nAverageHeightBefore == 0 || nAverageHeightAfter == 0) continue; if (! (nAverageHeightBefore >= nAverageHeightAfter * 2 || nAverageHeightAfter >= nAverageHeightBefore * 3)) { continue; } nPointSizeDifference = MAX (nAverageHeightBefore * 1000 / nAverageHeightAfter, nAverageHeightAfter * 1000 / nAverageHeightBefore); if (iBestPointSizeBreakingColumn == 0 || nPointSizeDifference > nBestPointSizeDifference) { iBestPointSizeBreakingColumn = iColumn; nBestPointSizeDifference = nPointSizeDifference; } } if (iBestPointSizeBreakingColumn != 0 && BlockBreakOnVertical (p, &q, &r, iBestPointSizeBreakingColumn + p -> Rect.xLeft, 0)) { # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 3) if(!LDPUMA_Skip(hBlocksBreaking)) { pDebugBlock = q; LT_GraphicsBlockOutput2 ("Block was breaked using " "Vert PointSizeAnalysis"); pDebugBlock = r; LT_GraphicsBlockOutput2 ("Block was breaked using " "Vert PointSizeAnalysis"); LT_Getch (); LT_GraphicsClearScreen (); } # endif return (TRUE); } return (FALSE); }