TextAnalyser.h 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138
  1. #pragma once
  2. #include <Bild.h>
  3. #include <Datei.h>
  4. #include <Fenster.h>
  5. #include <MausEreignis.h>
  6. #include <Schrift.h>
  7. #include <TastaturEreignis.h>
  8. #include <Text.h>
  9. #include <TextFeld.h>
  10. #include <Trie.h>
  11. #include <UIInitialization.h>
  12. Framework::Schrift* schrift;
  13. class CharMask
  14. {
  15. private:
  16. bool* mask;
  17. int width;
  18. int height;
  19. Framework::Text result;
  20. public:
  21. CharMask(Framework::Datei* d)
  22. {
  23. int l = 0;
  24. d->lese((char*)&l, 4);
  25. char* txt = new char[l + 1];
  26. d->lese(txt, l);
  27. txt[l] = 0;
  28. result.setText(txt, l);
  29. delete[] txt;
  30. d->lese((char*)&width, 4);
  31. d->lese((char*)&height, 4);
  32. mask = new bool[width * height];
  33. d->lese((char*)mask, width * height);
  34. }
  35. CharMask(int width, int height)
  36. {
  37. mask = new bool[width * height];
  38. this->width = width;
  39. this->height = height;
  40. for (int i = 0; i < width * height; i++)
  41. {
  42. mask[i] = 0;
  43. }
  44. result = "";
  45. }
  46. ~CharMask()
  47. {
  48. delete[] mask;
  49. }
  50. void save(Framework::Datei* d)
  51. {
  52. int l = result.getLength();
  53. d->schreibe((char*)&l, 4);
  54. d->schreibe(result.getText(), l);
  55. d->schreibe((char*)&width, 4);
  56. d->schreibe((char*)&height, 4);
  57. d->schreibe((char*)mask, width * height);
  58. }
  59. bool isEmpty()
  60. {
  61. return width == 0 && height == 0;
  62. }
  63. void adjustSize()
  64. {
  65. int maxX = 0;
  66. int maxY = 0;
  67. int minX = width;
  68. int minY = height;
  69. for (int x = 0; x < width; x++)
  70. {
  71. for (int y = 0; y < height; y++)
  72. {
  73. if (mask[y * width + x])
  74. {
  75. if (x > maxX) maxX = x;
  76. if (y > maxY) maxY = y;
  77. if (x < minX) minX = x;
  78. if (y < minY) minY = y;
  79. }
  80. }
  81. }
  82. if (maxX < minX || maxY < minY)
  83. {
  84. width = 0;
  85. height = 0;
  86. delete[] mask;
  87. mask = 0;
  88. return;
  89. }
  90. int newWidth = maxX - minX + 1;
  91. int newHeight = maxY - minY + 1;
  92. bool* newMask = new bool[newWidth * newHeight];
  93. for (int x = 0; x < newWidth; x++)
  94. {
  95. for (int y = 0; y < newHeight; y++)
  96. {
  97. newMask[y * newWidth + x]
  98. = mask[(minY + y) * width + (minX + x)];
  99. }
  100. }
  101. delete[] mask;
  102. mask = newMask;
  103. width = newWidth;
  104. height = newHeight;
  105. }
  106. bool toggleMask(int x, int y)
  107. {
  108. if (x < 0 || x >= width || y < 0 || y >= height)
  109. {
  110. return 0;
  111. }
  112. return mask[y * width + x] = !mask[y * width + x];
  113. }
  114. int getWidth()
  115. {
  116. return width;
  117. }
  118. int getHeight()
  119. {
  120. return height;
  121. }
  122. Framework::Text& getResult()
  123. {
  124. return result;
  125. }
  126. bool* getMask()
  127. {
  128. return mask;
  129. }
  130. int pixelCount()
  131. {
  132. int result = 0;
  133. for (int i = 0; i < width * height; i++)
  134. {
  135. if (mask[i])
  136. {
  137. result++;
  138. }
  139. }
  140. return result;
  141. }
  142. };
  143. Framework::Array<CharMask*>* chars;
  144. void saveChars()
  145. {
  146. Framework::Datei d("chars.dat");
  147. d.remove();
  148. d.erstellen();
  149. d.open(Framework::Datei::Style::schreiben);
  150. for (CharMask* charMask : *chars)
  151. {
  152. charMask->save(&d);
  153. }
  154. d.close();
  155. }
  156. void addChar(CharMask* charMask)
  157. {
  158. for (int i = 0; i < chars->getEintragAnzahl(); i++)
  159. {
  160. if (charMask->getWidth() * charMask->getHeight()
  161. > chars->get(i)->getWidth() * chars->get(i)->getHeight())
  162. {
  163. chars->add(charMask, i);
  164. return;
  165. }
  166. if (charMask->getWidth() * charMask->getHeight()
  167. == chars->get(i)->getWidth() * chars->get(i)->getHeight()
  168. && charMask->pixelCount() > chars->get(i)->pixelCount())
  169. {
  170. chars->add(charMask, i);
  171. return;
  172. }
  173. }
  174. chars->add(charMask);
  175. }
  176. void loadChars()
  177. {
  178. Framework::Trie<int> counts;
  179. chars = new Framework::Array<CharMask*>();
  180. Framework::Datei d("chars.dat");
  181. if (d.existiert())
  182. {
  183. d.open(Framework::Datei::Style::lesen);
  184. while (!d.istEnde())
  185. {
  186. CharMask* charMask = new CharMask(&d);
  187. counts.set(charMask->getResult().getText(),
  188. charMask->getResult().getLength(),
  189. counts.get(charMask->getResult().getText(),
  190. charMask->getResult().getLength())
  191. + 1);
  192. if (charMask->isEmpty() || !charMask->getResult().getLength())
  193. {
  194. delete charMask;
  195. continue;
  196. }
  197. // addChar(charMask);
  198. chars->add(charMask);
  199. }
  200. d.close();
  201. }
  202. Framework::Trie<bool> output;
  203. for (CharMask* mask : *chars)
  204. {
  205. if (!output.get(
  206. mask->getResult().getText(), mask->getResult().getLength()))
  207. {
  208. output.set(mask->getResult().getText(),
  209. mask->getResult().getLength(),
  210. true);
  211. std::cout << "Loaded "
  212. << counts.get(mask->getResult().getText(),
  213. mask->getResult().getLength())
  214. << " variants of '" << mask->getResult().getText() << "'"
  215. << std::endl;
  216. }
  217. }
  218. std::cout << "loaded " << chars->getEintragAnzahl() << " character variants"
  219. << std::endl;
  220. }
  221. struct Step
  222. {
  223. int x;
  224. int y;
  225. int width;
  226. int height;
  227. bool* map;
  228. Framework::Text result;
  229. };
  230. class TextAnalyser
  231. {
  232. private:
  233. int width;
  234. int height;
  235. bool* mask;
  236. int backgroundColor;
  237. Framework::Text result;
  238. bool image;
  239. Framework::WFenster* zf;
  240. Framework::BildZ* z;
  241. public:
  242. TextAnalyser(Framework::WFenster* zf)
  243. : width(0),
  244. height(0),
  245. mask(0),
  246. backgroundColor(0),
  247. image(0),
  248. zf(zf),
  249. z(0)
  250. {}
  251. ~TextAnalyser()
  252. {
  253. if (mask)
  254. {
  255. delete[] mask;
  256. }
  257. if (z)
  258. {
  259. zf->zBildschirm()->removeMember(z);
  260. }
  261. }
  262. RECT findRect(int width, int height, char* bitmapData)
  263. {
  264. RECT result = {0, 0, width, height};
  265. int x = 25;
  266. int y = 25;
  267. int stride = (width * 4);
  268. backgroundColor = (bitmapData[y * stride + x * 4] << 16 & 0x00FF0000)
  269. | (bitmapData[y * stride + x * 4 + 1] << 8 & 0x0000FF00)
  270. | (bitmapData[y * stride + x * 4 + 2] & 0x000000FF);
  271. bool inside = 1;
  272. for (int i = x; i > 0; i--)
  273. {
  274. int color = (bitmapData[y * stride + i * 4] << 16 & 0x00FF0000)
  275. | (bitmapData[y * stride + i * 4 + 1] << 8 & 0x0000FF00)
  276. | (bitmapData[y * stride + i * 4 + 2] & 0x000000FF);
  277. if (color != backgroundColor)
  278. {
  279. if (inside)
  280. {
  281. result.left = i + 1;
  282. }
  283. inside = 0;
  284. }
  285. else
  286. {
  287. inside = 1;
  288. }
  289. }
  290. inside = 1;
  291. for (int i = x; i < width; i++)
  292. {
  293. int color = (bitmapData[y * stride + i * 4] << 16 & 0x00FF0000)
  294. | (bitmapData[y * stride + i * 4 + 1] << 8 & 0x0000FF00)
  295. | (bitmapData[y * stride + i * 4 + 2] & 0x000000FF);
  296. if (color != backgroundColor)
  297. {
  298. if (inside)
  299. {
  300. result.right = i - 1;
  301. }
  302. inside = 0;
  303. }
  304. else
  305. {
  306. inside = 1;
  307. }
  308. }
  309. inside = 1;
  310. for (int i = y; i > 0; i--)
  311. {
  312. int color = (bitmapData[i * stride + x * 4] << 16 & 0x00FF0000)
  313. | (bitmapData[i * stride + x * 4 + 1] << 8 & 0x0000FF00)
  314. | (bitmapData[i * stride + x * 4 + 2] & 0x000000FF);
  315. if (color != backgroundColor)
  316. {
  317. if (inside)
  318. {
  319. result.top = i + 1;
  320. }
  321. inside = 0;
  322. }
  323. else
  324. {
  325. inside = 1;
  326. }
  327. }
  328. inside = 1;
  329. for (int i = y; i < height; i++)
  330. {
  331. int color = (bitmapData[i * stride + x * 4] << 16 & 0x00FF0000)
  332. | (bitmapData[i * stride + x * 4 + 1] << 8 & 0x0000FF00)
  333. | (bitmapData[i * stride + x * 4 + 2] & 0x000000FF);
  334. if (color != backgroundColor)
  335. {
  336. if (inside)
  337. {
  338. result.bottom = i - 1;
  339. }
  340. inside = 0;
  341. }
  342. else
  343. {
  344. inside = 1;
  345. }
  346. }
  347. result.top += 85;
  348. this->width = result.right - result.left;
  349. this->height = result.bottom - result.top;
  350. mask = new bool[width * height];
  351. for (int x = 0; x < this->width; x++)
  352. {
  353. for (int y = 0; y < this->height; y++)
  354. {
  355. int color = (bitmapData[(result.bottom - 1 - y) * stride
  356. + (result.left + x) * 4]
  357. << 16
  358. & 0x00FF0000)
  359. | (bitmapData[(result.bottom - 1 - y) * stride
  360. + (result.left + x) * 4 + 1]
  361. << 8
  362. & 0x0000FF00)
  363. | (bitmapData[(result.bottom - 1 - y) * stride
  364. + (result.left + x) * 4 + 2]
  365. & 0x000000FF);
  366. unsigned int r = bitmapData[(result.bottom - 1 - y) * stride
  367. + (result.left + x) * 4]
  368. & 0xFF;
  369. unsigned int g = bitmapData[(result.bottom - 1 - y) * stride
  370. + (result.left + x) * 4 + 1]
  371. & 0xFF;
  372. unsigned int b = bitmapData[(result.bottom - 1 - y) * stride
  373. + (result.left + x) * 4 + 2]
  374. & 0xFF;
  375. unsigned int bgr = ((backgroundColor & 0xFF0000) >> 16) & 0xFF;
  376. unsigned int bgg = ((backgroundColor & 0xFF00) >> 8) & 0xFF;
  377. unsigned int bgb = backgroundColor & 0xFF;
  378. int diff = std::abs((int)(bgr - r)) + std::abs((int)(bgg - g))
  379. + std::abs((int)(bgb - b));
  380. mask[y * this->width + x] = diff > 200;
  381. }
  382. }
  383. if (isEmpty(30, 0, this->width - 60, 20))
  384. {
  385. analyseParagraph(30, 55, this->width - 60, this->height - 55);
  386. }
  387. else
  388. {
  389. analyseParagraph(30, 0, this->width - 60, this->height);
  390. }
  391. return result;
  392. }
  393. bool isEmpty(int x, int y, int width, int height)
  394. {
  395. for (int i = 0; i < width; i++)
  396. {
  397. for (int j = 0; j < height; j++)
  398. {
  399. if (mask[(y + j) * this->width + (x + i)])
  400. {
  401. return false;
  402. }
  403. }
  404. }
  405. return true;
  406. }
  407. void analyseParagraph(int x, int y, int width, int height)
  408. {
  409. while (isEmpty(x, y, width, 1) && height > 0)
  410. {
  411. y++;
  412. height--;
  413. }
  414. while (isEmpty(x, y + height - 1, width, 1) && height > 0)
  415. {
  416. height--;
  417. }
  418. while (isEmpty(x, y, 1, height) && width > 0)
  419. {
  420. x++;
  421. width--;
  422. }
  423. while (isEmpty(x + width - 1, y, 1, height) && width > 0)
  424. {
  425. width--;
  426. }
  427. int mid = x + width / 2;
  428. if (isEmpty(mid - 3, y, 6, height))
  429. {
  430. analyseParagraph(x, y, mid - 3 - x, height);
  431. analyseParagraph(mid + 3, y, width / 2 - 3, height);
  432. }
  433. else
  434. {
  435. bool found = 0;
  436. for (int i = 1; i < height; i++)
  437. {
  438. if (isEmpty(x, y + i, width, 3))
  439. {
  440. analyseLine(x, y, width, i);
  441. y += i + 3;
  442. height -= i + 3;
  443. while (isEmpty(x, y, width, 1))
  444. {
  445. y++;
  446. height--;
  447. }
  448. i = 0;
  449. found = 1;
  450. }
  451. }
  452. if (found)
  453. {
  454. if (!isEmpty(x, y, width, height))
  455. {
  456. analyseLine(x, y, width, height);
  457. }
  458. }
  459. else
  460. {
  461. image = 1;
  462. }
  463. }
  464. }
  465. void analyseWord(int x, int y, int width, int height)
  466. {
  467. Framework::Array<Step> steps;
  468. while (true)
  469. {
  470. bool found = 0;
  471. for (CharMask* charMask : *chars)
  472. {
  473. if (charMask->getWidth() <= width
  474. && charMask->getHeight() <= height)
  475. {
  476. int yOffset = 0;
  477. while (yOffset + charMask->getHeight() <= height)
  478. {
  479. bool match = 1;
  480. for (int i = 0; i < charMask->getWidth(); i++)
  481. {
  482. for (int j = 0; j < charMask->getHeight(); j++)
  483. {
  484. if (charMask->getMask()[j * charMask->getWidth()
  485. + i]
  486. && !mask[(j + y + yOffset) * this->width + x
  487. + i])
  488. {
  489. match = 0;
  490. break;
  491. }
  492. }
  493. if (!match)
  494. {
  495. break;
  496. }
  497. }
  498. if (match
  499. && (charMask->getResult().istGleich(",")
  500. || charMask->getResult().istGleich(".")))
  501. {
  502. if (yOffset < (height - charMask->getHeight()) / 2)
  503. {
  504. match = 0;
  505. }
  506. }
  507. if (match)
  508. {
  509. if (charMask->getResult().istGleich("I")
  510. && steps.getEintragAnzahl() > 1
  511. && steps.get(steps.getEintragAnzahl() - 1)
  512. .result.istGleich("-")
  513. && steps.get(steps.getEintragAnzahl() - 2)
  514. .result.istGleich("I"))
  515. {
  516. std::cout << "warning: I-I detected"
  517. << std::endl;
  518. }
  519. if (steps.getEintragAnzahl() > 0
  520. && (steps.get(steps.getEintragAnzahl() - 1)
  521. .result.istGleich(",")
  522. || steps.get(steps.getEintragAnzahl() - 1)
  523. .result.istGleich(".")))
  524. {
  525. std::cout << "warning: . or , inside of a word "
  526. "detected"
  527. << std::endl;
  528. }
  529. Step step = {
  530. x, y, width, height, new bool[width * height]};
  531. step.result = charMask->getResult().getText();
  532. memset(step.map, 0, width * height);
  533. found = 1;
  534. for (int i = 0; i < charMask->getWidth(); i++)
  535. {
  536. for (int j = 0; j < charMask->getHeight(); j++)
  537. {
  538. if (charMask
  539. ->getMask()[j * charMask->getWidth()
  540. + i])
  541. {
  542. mask[(j + y + yOffset) * this->width + x
  543. + i]
  544. = 0;
  545. step.map[(j + yOffset) * width + i] = 1;
  546. }
  547. else
  548. {
  549. step.map[(j + yOffset) * width + i] = 0;
  550. }
  551. }
  552. }
  553. steps.add(step);
  554. break;
  555. }
  556. yOffset++;
  557. }
  558. }
  559. }
  560. if (!found)
  561. {
  562. Framework::Text word;
  563. for (const Step& step : steps)
  564. {
  565. word.append(step.result.getText());
  566. }
  567. std::cout << "What comes after: " << word.getText()
  568. << std::endl;
  569. while (!render(x, y, width, height))
  570. {
  571. if (steps.getEintragAnzahl() > 0)
  572. {
  573. Step last = steps.get(steps.getEintragAnzahl() - 1);
  574. steps.remove(steps.getEintragAnzahl() - 1);
  575. x = last.x;
  576. y = last.y;
  577. width = last.width;
  578. height = last.height;
  579. for (int i = 0; i < width; i++)
  580. {
  581. for (int j = 0; j < height; j++)
  582. {
  583. if (last.map[j * width + i])
  584. {
  585. mask[(j + y) * this->width + x + i] = 1;
  586. }
  587. }
  588. }
  589. delete[] last.map;
  590. }
  591. }
  592. }
  593. else
  594. {
  595. while (isEmpty(x, y, 1, height) && width > 0)
  596. {
  597. x++;
  598. width--;
  599. }
  600. while (isEmpty(x, y, width, 1) && height > 0)
  601. {
  602. y++;
  603. height--;
  604. }
  605. while (isEmpty(x + width - 1, y, 1, height) && width > 0)
  606. {
  607. width--;
  608. }
  609. while (isEmpty(x, y + height - 1, width, 1) && height > 0)
  610. {
  611. height--;
  612. }
  613. }
  614. if (width <= 0 || height <= 0)
  615. {
  616. break;
  617. }
  618. }
  619. Framework::Text word;
  620. for (const Step& step : steps)
  621. {
  622. word.append(step.result.getText());
  623. delete[] step.map;
  624. }
  625. std::cout << "Read word: " << word.getText() << std::endl;
  626. this->result.append() << word.getText() << " ";
  627. }
  628. void analyseLine(int x, int y, int width, int height)
  629. {
  630. int blankWidth = 3;
  631. while (isEmpty(x, y, 1, height) && width > 0)
  632. {
  633. x++;
  634. width--;
  635. }
  636. while (isEmpty(x + width - 1, y, 1, height) && width > 0)
  637. {
  638. width--;
  639. }
  640. for (int i = 1; i < width; i++)
  641. {
  642. if (isEmpty(x + i, y, blankWidth, height))
  643. {
  644. analyseWord(x, y, i, height);
  645. x += i + blankWidth;
  646. width -= i + blankWidth;
  647. while (isEmpty(x, y, 1, height))
  648. {
  649. x++;
  650. width--;
  651. }
  652. i = 0;
  653. }
  654. }
  655. if (width > 0 && !isEmpty(x, y, width, height))
  656. {
  657. analyseWord(x, y, width, height);
  658. }
  659. if (result.getLength() > 1
  660. && result.getText()[result.getLength() - 2]
  661. == '.') // last char is allways space
  662. {
  663. result.append() << "<br>";
  664. }
  665. result.append() << "\n";
  666. }
  667. bool render(int x, int y, int width, int height)
  668. {
  669. CharMask* charMask = new CharMask(width, height);
  670. int factor = 5;
  671. zf->setSize(width * factor + 10, height * factor + 35);
  672. Framework::Bildschirm* screen = zf->zBildschirm();
  673. zf->setAnzeigeModus(1);
  674. screen->setBackBufferSize(width * factor + 10, height * factor + 35);
  675. screen->update();
  676. if (z)
  677. {
  678. screen->removeMember(z);
  679. }
  680. z = new Framework::BildZ();
  681. Framework::Bild* b = new Framework::Bild();
  682. b->neuBild(width * factor, height * factor, 0xFF000000);
  683. for (int i = 0; i < width * factor; i++)
  684. {
  685. for (int j = 0; j < height * factor; j++)
  686. {
  687. if (mask[(j / factor + y) * this->width + i / factor + x])
  688. {
  689. b->setPixelDP(i, j, 0xFFFFFFFF);
  690. }
  691. }
  692. }
  693. z->setBildZ(b);
  694. z->setSize(width * factor, height * factor);
  695. z->setPosition(5, 5);
  696. z->setStyle(Framework::BildZ::Style::Sichtbar
  697. | Framework::BildZ::Style::Erlaubt);
  698. Framework::UIInit init = Framework::defaultUI(schrift, screen);
  699. Framework::TextFeld* tf = init.createTextFeld(init.initParam);
  700. tf->setSize(width * factor, 20);
  701. tf->setStyle(Framework::TextFeld::Style::TextFeld);
  702. tf->setPosition(5, height * factor + 10);
  703. tf->setText("");
  704. tf->setMausEreignis(Framework::_ret1ME);
  705. tf->setTastaturEreignis(Framework::_ret1TE);
  706. screen->addMember(tf);
  707. screen->addMember(z);
  708. screen->render();
  709. bool wait = 1;
  710. int lastX = 0;
  711. int lastY = 0;
  712. bool currentState = 0;
  713. bool aborted = 0;
  714. int size = 3;
  715. z->setMausEreignis([&wait,
  716. b,
  717. &charMask,
  718. width,
  719. height,
  720. factor,
  721. screen,
  722. this,
  723. x,
  724. y,
  725. &lastX,
  726. &lastY,
  727. &currentState,
  728. &aborted,
  729. &size,
  730. tf](
  731. void* z, void* p, Framework::MausEreignis me) {
  732. if (me.id == Framework::ME_PRechts)
  733. {
  734. charMask->adjustSize();
  735. if (charMask->isEmpty())
  736. {
  737. delete charMask;
  738. charMask = new CharMask(width, height);
  739. }
  740. else
  741. {
  742. if (tf->getText()->getLength() > 0)
  743. {
  744. wait = 0;
  745. }
  746. }
  747. }
  748. if (me.id == Framework::ME_PMitte)
  749. {
  750. aborted = 1;
  751. wait = 0;
  752. }
  753. if (me.id == Framework::ME_PLinks)
  754. {
  755. if (mask[(me.my / factor + y) * this->width + me.mx / factor
  756. + x])
  757. {
  758. currentState
  759. = charMask->toggleMask(me.mx / factor, me.my / factor);
  760. for (int x2 = -size / 2; x2 < (size - size / 2); x2++)
  761. {
  762. for (int y2 = -size / 2; y2 < (size - size / 2); y2++)
  763. {
  764. if (me.my / factor + y2 >= 0
  765. && me.my / factor + y2 < charMask->getHeight()
  766. && me.my / factor + y2 + y < this->height
  767. && me.mx / factor + x2 >= 0
  768. && me.mx / factor + x2 < charMask->getWidth()
  769. && me.mx / factor + x2 + x < this->width)
  770. {
  771. if (mask[(me.my / factor + y2 + y) * this->width
  772. + me.mx / factor + x2 + x])
  773. {
  774. charMask
  775. ->getMask()[(me.my / factor + y2)
  776. * charMask->getWidth()
  777. + me.mx / factor + x2]
  778. = currentState;
  779. for (int xx = 0; xx < factor; xx++)
  780. {
  781. for (int yy = 0; yy < factor; yy++)
  782. {
  783. if (currentState)
  784. {
  785. b->setPixelDP(
  786. (me.mx / factor + x2)
  787. * factor
  788. + xx,
  789. (me.my / factor + y2)
  790. * factor
  791. + yy,
  792. 0xFF00FF00);
  793. }
  794. else
  795. {
  796. b->setPixelDP(
  797. (me.mx / factor + x2)
  798. * factor
  799. + xx,
  800. (me.my / factor + y2)
  801. * factor
  802. + yy,
  803. 0xFFFFFFFF);
  804. }
  805. }
  806. }
  807. }
  808. }
  809. }
  810. }
  811. }
  812. screen->render();
  813. }
  814. if (me.id == Framework::ME_Bewegung)
  815. {
  816. int px = me.mx / factor;
  817. int py = me.my / factor;
  818. if (px != lastX || py != lastY)
  819. {
  820. for (int x2 = -size / 2; x2 < (size - size / 2); x2++)
  821. {
  822. for (int y2 = -size / 2; y2 < (size - size / 2); y2++)
  823. {
  824. if (lastY + y2 >= 0
  825. && lastY + y2 < charMask->getHeight()
  826. && lastY + y2 + y < this->height
  827. && lastX + x2 >= 0
  828. && lastX + x2 < charMask->getWidth()
  829. && lastX + x2 + x < this->width)
  830. {
  831. if (charMask
  832. ->getMask()[(lastY + y2)
  833. * charMask->getWidth()
  834. + lastX + x2])
  835. {
  836. for (int x = 0; x < factor; x++)
  837. {
  838. for (int y = 0; y < factor; y++)
  839. {
  840. b->setPixelDP(
  841. (lastX + x2) * factor + x,
  842. (lastY + y2) * factor + y,
  843. 0xFF00FF00);
  844. }
  845. }
  846. }
  847. else
  848. {
  849. if (mask[(lastY + y + y2) * this->width
  850. + lastX + x + x2])
  851. {
  852. for (int x = 0; x < factor; x++)
  853. {
  854. for (int y = 0; y < factor; y++)
  855. {
  856. b->setPixelDP(
  857. (lastX + x2) * factor + x,
  858. (lastY + y2) * factor + y,
  859. 0xFFFFFFFF);
  860. }
  861. }
  862. }
  863. }
  864. }
  865. }
  866. }
  867. for (int x2 = -size / 2; x2 < (size - size / 2); x2++)
  868. {
  869. for (int y2 = -size / 2; y2 < (size - size / 2); y2++)
  870. {
  871. if (py + y2 >= 0 && py + y2 < charMask->getHeight()
  872. && py + y2 + y < this->height && px + x2 >= 0
  873. && px + x2 < charMask->getWidth()
  874. && px + x2 + x < this->width)
  875. {
  876. if (mask[(py + y + y2) * this->width + px + x
  877. + x2])
  878. {
  879. for (int x = 0; x < factor; x++)
  880. {
  881. for (int y = 0; y < factor; y++)
  882. {
  883. b->setPixelDP(
  884. (px + x2) * factor + x,
  885. (py + y2) * factor + y,
  886. 0xFFFFA000);
  887. }
  888. }
  889. if (Framework::getMausStand(
  890. Framework::M_Links))
  891. {
  892. charMask->getMask()
  893. [(py + y2) * charMask->getWidth()
  894. + px + x2]
  895. = currentState;
  896. if (currentState)
  897. {
  898. for (int x = 0; x < factor; x++)
  899. {
  900. for (int y = 0; y < factor; y++)
  901. {
  902. b->setPixelDP(
  903. (px + x2) * factor + x,
  904. (py + y2) * factor + y,
  905. 0xFF00FF00);
  906. }
  907. }
  908. }
  909. }
  910. }
  911. }
  912. }
  913. }
  914. screen->render();
  915. lastX = px;
  916. lastY = py;
  917. }
  918. }
  919. return true;
  920. });
  921. z->setTastaturEreignis([&size,
  922. screen,
  923. tf,
  924. this,
  925. charMask,
  926. x,
  927. y,
  928. width,
  929. height,
  930. factor,
  931. b](void* z,
  932. void* p,
  933. Framework::TastaturEreignis te) {
  934. if (te.id == Framework::TE_Press && te.taste[0] == '+')
  935. {
  936. size++;
  937. }
  938. if (te.id == Framework::TE_Press && te.taste[0] == '-' && size > 1)
  939. {
  940. size--;
  941. }
  942. if (te.id == Framework::TE_Press && te.virtualKey == 'I'
  943. && Framework::getTastenStand(Framework::T_Strg))
  944. {
  945. if (!tf->zText()->hat("<i>"))
  946. {
  947. tf->setText(Framework::Text("<i>") + tf->zText()->getText()
  948. + "</i>");
  949. }
  950. }
  951. if (te.id == Framework::TE_Press && te.virtualKey == 'U'
  952. && Framework::getTastenStand(Framework::T_Strg))
  953. {
  954. if (!tf->zText()->hat("<u>"))
  955. {
  956. tf->setText(Framework::Text("<u>") + tf->zText()->getText()
  957. + "</u>");
  958. }
  959. }
  960. if (te.id == Framework::TE_Press && te.virtualKey == 'B'
  961. && Framework::getTastenStand(Framework::T_Strg))
  962. {
  963. if (!tf->zText()->hat("<b>"))
  964. {
  965. tf->setText(Framework::Text("<b>") + tf->zText()->getText()
  966. + "</b>");
  967. }
  968. }
  969. if (te.id == Framework::TE_Press && te.taste[0] == ' ')
  970. {
  971. bool hasAny = 0;
  972. for (int x = 0; x < charMask->getWidth(); x++)
  973. {
  974. for (int y = 0; y < charMask->getHeight(); y++)
  975. {
  976. if (charMask->getMask()[y * charMask->getWidth() + x])
  977. {
  978. hasAny = 1;
  979. }
  980. }
  981. }
  982. if (!hasAny)
  983. {
  984. bool first = 1;
  985. for (int xx = x; xx < x + width && first; xx++)
  986. {
  987. for (int yy = y; yy < y + height && first; yy++)
  988. {
  989. if (mask[yy * this->width + xx]
  990. && (yy - y) < charMask->getHeight()
  991. && (xx - x) < charMask->getWidth())
  992. {
  993. if (first)
  994. {
  995. charMask
  996. ->getMask()[(yy - y)
  997. * charMask->getWidth()
  998. + (xx - x)]
  999. = 1;
  1000. }
  1001. first = 0;
  1002. }
  1003. }
  1004. }
  1005. }
  1006. bool changed = 1;
  1007. while (changed)
  1008. {
  1009. changed = 0;
  1010. for (int xx = x; xx < x + width; xx++)
  1011. {
  1012. for (int yy = y; yy < y + height; yy++)
  1013. {
  1014. if (mask[yy * this->width + xx]
  1015. && yy - y < charMask->getHeight()
  1016. && xx - x < charMask->getWidth()
  1017. && !charMask
  1018. ->getMask()[(yy - y) * charMask->getWidth()
  1019. + xx - x])
  1020. {
  1021. bool hasNeighbor = 0;
  1022. for (int i = -1; i <= 1 && !hasNeighbor; i++)
  1023. {
  1024. for (int j = -1; j <= 1 && !hasNeighbor;
  1025. j++)
  1026. {
  1027. if (yy - y + j >= 0
  1028. && yy - y + j
  1029. < charMask->getHeight()
  1030. && xx - x + i >= 0
  1031. && xx - x + i
  1032. < charMask->getWidth())
  1033. {
  1034. hasNeighbor
  1035. |= charMask->getMask()
  1036. [(yy - y + j)
  1037. * charMask
  1038. ->getWidth()
  1039. + xx - x + i];
  1040. }
  1041. }
  1042. }
  1043. if (hasNeighbor)
  1044. {
  1045. charMask
  1046. ->getMask()[(yy - y)
  1047. * charMask->getWidth()
  1048. + xx - x]
  1049. = 1;
  1050. changed = 1;
  1051. }
  1052. }
  1053. }
  1054. }
  1055. }
  1056. for (int i = 0; i < width * factor; i++)
  1057. {
  1058. for (int j = 0; j < height * factor; j++)
  1059. {
  1060. if (mask[(j / factor + y) * this->width + i / factor
  1061. + x])
  1062. {
  1063. if (charMask->getMask()[(j / factor)
  1064. * charMask->getWidth()
  1065. + i / factor])
  1066. {
  1067. b->setPixelDP(i, j, 0xFF00FF00);
  1068. }
  1069. else
  1070. {
  1071. b->setPixelDP(i, j, 0xFFFFFFFF);
  1072. }
  1073. }
  1074. }
  1075. }
  1076. tf->addStyle(Framework::TextFeld::Style::Fokus);
  1077. }
  1078. screen->render();
  1079. return te.taste[0] == ' ';
  1080. });
  1081. while (wait)
  1082. {
  1083. Sleep(100);
  1084. }
  1085. if (!aborted)
  1086. {
  1087. charMask->getResult().setText(tf->zText()->getText());
  1088. addChar(charMask);
  1089. saveChars();
  1090. }
  1091. else
  1092. {
  1093. delete charMask;
  1094. }
  1095. screen->lock();
  1096. screen->removeMember(tf);
  1097. screen->unlock();
  1098. return !aborted;
  1099. }
  1100. bool hasImage() const
  1101. {
  1102. return image;
  1103. }
  1104. void writeToFile(Framework::Datei& dat)
  1105. {
  1106. dat.schreibe(result.getText(), result.getLength());
  1107. }
  1108. };