summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Hirt <hirt.danny@gmail.com>2017-10-15 17:55:20 +0300
committerCedric BAIL <cedric@osg.samsung.com>2017-11-10 10:30:04 -0800
commitc7b2372ffb35cc51415f943b7ff2895d245362bc (patch)
treec16a1438d36a17013c861e6e2f8acf7c82408cbf /src
parent58ce1d654b0d4ead58bba384b1e1edd5b605bc4e (diff)
Edje: move textblock handling to a separate source
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
Diffstat (limited to 'src')
-rw-r--r--src/Makefile_Edje.am1
-rw-r--r--src/lib/edje/edje_calc.c577
-rw-r--r--src/lib/edje/edje_private.h12
-rw-r--r--src/lib/edje/edje_textblock.c583
4 files changed, 596 insertions, 577 deletions
diff --git a/src/Makefile_Edje.am b/src/Makefile_Edje.am
index e1a1973430..fd7c903e38 100644
--- a/src/Makefile_Edje.am
+++ b/src/Makefile_Edje.am
@@ -96,6 +96,7 @@ lib/edje/edje_multisense.c \
96lib/edje/edje_program.c \ 96lib/edje/edje_program.c \
97lib/edje/edje_smart.c \ 97lib/edje/edje_smart.c \
98lib/edje/edje_text.c \ 98lib/edje/edje_text.c \
99lib/edje/edje_textblock.c \
99lib/edje/edje_textblock_styles.c \ 100lib/edje/edje_textblock_styles.c \
100lib/edje/edje_util.c \ 101lib/edje/edje_util.c \
101lib/edje/edje_legacy.c \ 102lib/edje/edje_legacy.c \
diff --git a/src/lib/edje/edje_calc.c b/src/lib/edje/edje_calc.c
index 3cfa5dc924..1442cb8f14 100644
--- a/src/lib/edje/edje_calc.c
+++ b/src/lib/edje/edje_calc.c
@@ -1453,583 +1453,6 @@ _edje_part_recalc_single_step(Edje_Part_Description_Common *desc,
1453 } 1453 }
1454} 1454}
1455 1455
1456static double
1457_edje_part_recalc_single_textblock_scale_range_adjust(Edje_Part_Description_Text *chosen_desc, double base_scale, double scale)
1458{
1459 double size, min, max;
1460
1461 if (chosen_desc->text.size == 0)
1462 return scale;
1463
1464 min = base_scale * chosen_desc->text.size_range_min;
1465 max = chosen_desc->text.size_range_max * base_scale;
1466 size = chosen_desc->text.size * scale;
1467
1468 if ((size > max) && (max > 0))
1469 scale = max / (double)chosen_desc->text.size;
1470 else if (size < min)
1471 scale = min / (double)chosen_desc->text.size;
1472
1473 return scale;
1474}
1475
1476/*
1477 * Legacy function for min/max calculation of textblock part.
1478 * It can't calculate min/max properly in many cases.
1479 *
1480 * To keep backward compatibility, it will be used for old version of EDJ files.
1481 * You can't see proper min/max result accroding to documents with this function.
1482 */
1483static void
1484_edje_part_recalc_single_textblock_min_max_calc_legacy(Edje_Real_Part *ep,
1485 Edje_Part_Description_Text *chosen_desc,
1486 Edje_Calc_Params *params,
1487 int *minw, int *minh,
1488 int *maxw, int *maxh)
1489{
1490 Evas_Coord tw, th, ins_l, ins_r, ins_t, ins_b;
1491
1492 /* Legacy code for Textblock min/max calculation */
1493 if ((chosen_desc->text.min_x) || (chosen_desc->text.min_y))
1494 {
1495 int mw = 0, mh = 0;
1496
1497 tw = th = 0;
1498 if (!chosen_desc->text.min_x)
1499 {
1500 efl_gfx_size_set(ep->object, EINA_SIZE2D(TO_INT(params->eval.w), TO_INT(params->eval.h)));
1501 efl_canvas_text_size_formatted_get(ep->object, &tw, &th);
1502 }
1503 else
1504 evas_object_textblock_size_native_get(ep->object, &tw, &th);
1505 evas_object_textblock_style_insets_get(ep->object, &ins_l,
1506 &ins_r, &ins_t, &ins_b);
1507 mw = ins_l + tw + ins_r;
1508 mh = ins_t + th + ins_b;
1509 if (minw && chosen_desc->text.min_x)
1510 {
1511 if (mw > *minw) *minw = mw;
1512 }
1513 if (minh && chosen_desc->text.min_y)
1514 {
1515 if (mh > *minh) *minh = mh;
1516 }
1517 }
1518
1519 if ((chosen_desc->text.max_x) || (chosen_desc->text.max_y))
1520 {
1521 int mw = 0, mh = 0;
1522
1523 tw = th = 0;
1524 if (!chosen_desc->text.max_x)
1525 {
1526 efl_gfx_size_set(ep->object, EINA_SIZE2D(TO_INT(params->eval.w), TO_INT(params->eval.h)));
1527 efl_canvas_text_size_formatted_get(ep->object, &tw, &th);
1528 }
1529 else
1530 evas_object_textblock_size_native_get(ep->object, &tw, &th);
1531 evas_object_textblock_style_insets_get(ep->object, &ins_l, &ins_r,
1532 &ins_t, &ins_b);
1533 mw = ins_l + tw + ins_r;
1534 mh = ins_t + th + ins_b;
1535 if (maxw && chosen_desc->text.max_x)
1536 {
1537 if (mw > *maxw) *maxw = mw;
1538 if (minw && (*maxw < *minw)) *maxw = *minw;
1539 }
1540 if (maxh && chosen_desc->text.max_y)
1541 {
1542 if (mh > *maxh) *maxh = mh;
1543 if (minh && (*maxh < *minh)) *maxh = *minh;
1544 }
1545 }
1546}
1547
1548static void
1549_edje_part_recalc_single_textblock_min_max_calc(Edje_Real_Part *ep,
1550 Edje_Part_Description_Text *chosen_desc,
1551 Edje_Calc_Params *params,
1552 int *minw, int *minh,
1553 int *maxw, int *maxh)
1554{
1555 Evas_Coord tw, th, ins_l, ins_r, ins_t, ins_b;
1556 Evas_Coord min_calc_w = 0, min_calc_h = 0;
1557
1558 /* min_calc_* values need to save calculated minumum size
1559 * for maximum size calculation */
1560 if (minw) min_calc_w = *minw;
1561 if (minh) min_calc_h = *minh;
1562
1563 if ((chosen_desc->text.min_x) || (chosen_desc->text.min_y))
1564 {
1565 evas_object_textblock_style_insets_get(ep->object, &ins_l,
1566 &ins_r, &ins_t, &ins_b);
1567
1568 tw = th = 0;
1569 if (!chosen_desc->text.min_x)
1570 {
1571 /* text.min: 0 1
1572 * text.max: X X */
1573 int temp_h = TO_INT(params->eval.h);
1574 int temp_w = TO_INT(params->eval.w);
1575
1576 if (min_calc_w > temp_w)
1577 temp_w = min_calc_w;
1578 if ((!chosen_desc->text.max_x) &&
1579 maxw && (*maxw > -1) && (*maxw < temp_w))
1580 temp_w = *maxw;
1581
1582 if (chosen_desc->text.max_y)
1583 {
1584 /* text.min: 0 1
1585 * text.max: X 1 */
1586 temp_h = INT_MAX / 10000;
1587 }
1588 else if (maxh && (*maxh > TO_INT(params->eval.h)))
1589 {
1590 /* text.min: 0 1
1591 * text.max: X 0
1592 * And there is a limit for height. */
1593 temp_h = *maxh;
1594 }
1595
1596 /* If base width for calculation is 0,
1597 * don't get meaningless height for multiline */
1598 if (temp_w > 0)
1599 {
1600 efl_gfx_size_set(ep->object, EINA_SIZE2D(temp_w, temp_h));
1601 efl_canvas_text_size_formatted_get(ep->object, &tw, &th);
1602
1603 tw += ins_l + ins_r;
1604 th += ins_t + ins_b;
1605 }
1606 else
1607 {
1608 efl_canvas_text_size_native_get(ep->object, NULL, &th);
1609
1610 th += ins_t + ins_b;
1611 }
1612 }
1613 else
1614 {
1615 /* text.min: 1 X
1616 * text.max: X X */
1617 if (chosen_desc->text.min_y && (!chosen_desc->text.max_x) &&
1618 maxw && (*maxw > -1))
1619 {
1620 /* text.min: 1 1
1621 * text.max: 0 X */
1622 int temp_w, temp_h;
1623
1624 temp_w = *maxw;
1625 temp_h = INT_MAX / 10000;
1626
1627 if (min_calc_w > temp_w)
1628 temp_w = min_calc_w;
1629
1630 if ((!chosen_desc->text.max_y) && maxh && (*maxh > -1))
1631 {
1632 /* text.min: 1 1
1633 * text.max: 0 0
1634 * There is limit for height. */
1635 temp_h = *maxh;
1636 }
1637
1638 efl_gfx_size_set(ep->object, EINA_SIZE2D(temp_w, temp_h));
1639 efl_canvas_text_size_formatted_get(ep->object, &tw, &th);
1640
1641 tw += ins_l + ins_r;
1642 th += ins_t + ins_b;
1643
1644 /* If base width for calculation is 0,
1645 * don't get meaningless height for multiline */
1646 if (temp_w <= 0)
1647 {
1648 efl_canvas_text_size_native_get(ep->object, NULL, &th);
1649
1650 th += ins_t + ins_b;
1651 }
1652 }
1653 else
1654 {
1655 /* text.min: 1 X
1656 * text.max: 1 X
1657 * Or,
1658 * text.min: 1 X
1659 * text.max: 0 X without max width.
1660 * It is a singleline Textblock. */
1661 efl_canvas_text_size_native_get(ep->object, &tw, &th);
1662
1663 tw += ins_l + ins_r;
1664 th += ins_t + ins_b;
1665
1666 if (!chosen_desc->text.max_x &&
1667 (maxw && (*maxw > -1) && (*maxw < tw)))
1668 {
1669 /* text.min: 1 0
1670 * text.max: 0 X */
1671 tw = *maxw;
1672 }
1673 }
1674 }
1675
1676 if (tw > min_calc_w) min_calc_w = tw;
1677 if (th > min_calc_h) min_calc_h = th;
1678 if (chosen_desc->text.min_x && minw) *minw = min_calc_w;
1679 if (chosen_desc->text.min_y && minh) *minh = min_calc_h;
1680 }
1681
1682 if ((chosen_desc->text.max_x) || (chosen_desc->text.max_y))
1683 {
1684 evas_object_textblock_style_insets_get(ep->object, &ins_l, &ins_r,
1685 &ins_t, &ins_b);
1686
1687 tw = th = 0;
1688 if (!chosen_desc->text.max_x)
1689 {
1690 /* text.min: X X
1691 * text.max: 0 1 */
1692 int temp_w, temp_h;
1693
1694 if (chosen_desc->text.min_y)
1695 {
1696 /* text.min: X 1
1697 * text.max: 0 1
1698 * Already calculated in text for height. */
1699 tw = TO_INT(params->eval.w);
1700 if (min_calc_w > tw)
1701 tw = min_calc_w;
1702
1703 th = min_calc_h;
1704 }
1705 else
1706 {
1707 /* text.min: X 0
1708 * text.max: 0 1 */
1709 temp_w = TO_INT(params->eval.w);
1710 temp_h = TO_INT(params->eval.h);
1711
1712 if (min_calc_w > temp_w)
1713 temp_w = min_calc_w;
1714 if (maxw && (*maxw > -1) && (*maxw < temp_w))
1715 temp_w = *maxw;
1716 if (min_calc_h > temp_h)
1717 temp_h = min_calc_h;
1718
1719 /* If base width for calculation is 0,
1720 * don't get meaningless height for multiline */
1721 if (temp_w > 0)
1722 {
1723 efl_gfx_size_set(ep->object, EINA_SIZE2D(temp_w, temp_h));
1724 efl_canvas_text_size_formatted_get(ep->object, &tw, &th);
1725
1726 tw += ins_l + ins_r;
1727 th += ins_t + ins_b;
1728 }
1729 else
1730 {
1731 efl_canvas_text_size_native_get(ep->object, NULL, &th);
1732
1733 th += ins_t + ins_b;
1734 }
1735 }
1736 }
1737 else
1738 {
1739 /* text.max: 1 X */
1740 if (chosen_desc->text.min_x)
1741 {
1742 /* text.min: 1 X
1743 * text.max: 1 X
1744 * Singleline. */
1745 efl_canvas_text_size_native_get(ep->object, &tw, &th);
1746
1747 tw += ins_l + ins_r;
1748 th += ins_t + ins_b;
1749 }
1750 else
1751 {
1752 /* text.min: 0 X
1753 * text.max: 1 X */
1754 if (chosen_desc->text.max_y)
1755 {
1756 /* text.min: 0 X
1757 * text.max: 1 1 */
1758 int temp_w, temp_h;
1759
1760 temp_w = TO_INT(params->eval.w);
1761 temp_h = TO_INT(params->eval.h);
1762
1763 if (min_calc_w > temp_w)
1764 temp_w = min_calc_w;
1765 if (min_calc_h > temp_h)
1766 temp_h = min_calc_h;
1767
1768 if (chosen_desc->text.min_y)
1769 {
1770 /* text.min: 0 1
1771 * text.max: 1 1
1772 * There is no need to calculate it again. */
1773 tw = min_calc_w;
1774 th = min_calc_h;
1775 }
1776 else
1777 {
1778 /* text.min: 0 0
1779 * text.max: 1 1 */
1780
1781 efl_gfx_size_set(ep->object, EINA_SIZE2D(temp_w, temp_h));
1782 efl_canvas_text_size_formatted_get(ep->object, &tw, &th);
1783
1784 tw += ins_l + ins_r;
1785 th += ins_t + ins_b;
1786
1787 /* If base width for calculation is 0,
1788 * don't get meaningless height for multiline */
1789 if (temp_w <= 0)
1790 {
1791 efl_canvas_text_size_native_get(ep->object, NULL, &th);
1792
1793 th += ins_t + ins_b;
1794 }
1795 }
1796 }
1797 else
1798 {
1799 /* text.min: 0 X
1800 * text.max: 1 0 */
1801 int temp_w, temp_h;
1802
1803 temp_w = TO_INT(params->eval.w);
1804 if (min_calc_w > temp_w)
1805 temp_w = min_calc_w;
1806
1807 temp_h = efl_gfx_size_get(ep->object).h;
1808 efl_gfx_size_set(ep->object, EINA_SIZE2D(temp_w, temp_h));
1809 efl_canvas_text_size_formatted_get(ep->object, &tw, &th);
1810
1811 tw += ins_l + ins_r;
1812 th += ins_t + ins_b;
1813
1814 /* If base width for calculation is 0,
1815 * don't get meaningless height for multiline */
1816 if (temp_w <= 0)
1817 {
1818 efl_canvas_text_size_native_get(ep->object, NULL, &th);
1819
1820 th += ins_t + ins_b;
1821 }
1822 }
1823 }
1824 }
1825
1826 if (maxw && chosen_desc->text.max_x)
1827 {
1828 if (tw > *maxw) *maxw = tw;
1829 if (minw && (*maxw < *minw)) *maxw = *minw;
1830 }
1831 if (maxh && chosen_desc->text.max_y)
1832 {
1833 if (th > *maxh) *maxh = th;
1834 if (minh && (*maxh < *minh)) *maxh = *minh;
1835 }
1836 }
1837}
1838
1839static void
1840_edje_part_recalc_single_textblock(FLOAT_T sc,
1841 Edje *ed,
1842 Edje_Real_Part *ep,
1843 Edje_Part_Description_Text *chosen_desc,
1844 Edje_Calc_Params *params,
1845 int *minw, int *minh,
1846 int *maxw, int *maxh)
1847{
1848 if ((ep->type != EDJE_RP_TYPE_TEXT) ||
1849 (!ep->typedata.text))
1850 return;
1851
1852 if (chosen_desc)
1853 {
1854 Evas_Coord tw, th;
1855 const char *text = "";
1856 const char *style = "";
1857 Edje_Style *stl = NULL;
1858 const char *tmp;
1859 Eina_List *l;
1860
1861 if (chosen_desc->text.id_source >= 0)
1862 {
1863 Edje_Part_Description_Text *et;
1864
1865 ep->typedata.text->source = ed->table_parts[chosen_desc->text.id_source % ed->table_parts_size];
1866
1867 et = _edje_real_part_text_source_description_get(ep, NULL);
1868 tmp = edje_string_get(&et->text.style);
1869 if (tmp) style = tmp;
1870 }
1871 else
1872 {
1873 ep->typedata.text->source = NULL;
1874
1875 tmp = edje_string_get(&chosen_desc->text.style);
1876 if (tmp) style = tmp;
1877 }
1878
1879 if (chosen_desc->text.id_text_source >= 0)
1880 {
1881 Edje_Part_Description_Text *et;
1882 Edje_Real_Part *rp;
1883
1884 ep->typedata.text->text_source = ed->table_parts[chosen_desc->text.id_text_source % ed->table_parts_size];
1885
1886 et = _edje_real_part_text_text_source_description_get(ep, &rp);
1887 text = edje_string_get(&et->text.text);
1888
1889 if (rp->typedata.text->text) text = rp->typedata.text->text;
1890 }
1891 else
1892 {
1893 ep->typedata.text->text_source = NULL;
1894 text = edje_string_get(&chosen_desc->text.text);
1895 if (ep->typedata.text->text) text = ep->typedata.text->text;
1896 }
1897
1898 EINA_LIST_FOREACH(ed->file->styles, l, stl)
1899 {
1900 if ((stl->name) && (!strcmp(stl->name, style))) break;
1901 stl = NULL;
1902 }
1903
1904 if (ep->part->scale)
1905 evas_object_scale_set(ep->object, TO_DOUBLE(sc));
1906
1907 if ((chosen_desc->text.fit_x) || (chosen_desc->text.fit_y))
1908 {
1909 double base_s = 1.0;
1910 double orig_s;
1911 double s = base_s;
1912
1913 if (ep->part->scale) base_s = TO_DOUBLE(sc);
1914 efl_canvas_object_scale_set(ep->object, base_s);
1915 efl_canvas_text_size_native_get(ep->object, &tw, &th);
1916
1917 orig_s = base_s;
1918 /* Now make it bigger so calculations will be more accurate
1919 * and less influenced by hinting... */
1920 {
1921 orig_s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s,
1922 orig_s * TO_INT(params->eval.w) / tw);
1923 efl_canvas_object_scale_set(ep->object, orig_s);
1924 efl_canvas_text_size_native_get(ep->object, &tw, &th);
1925 }
1926 if (chosen_desc->text.fit_x)
1927 {
1928 if (tw > 0)
1929 {
1930 s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s,
1931 orig_s * TO_INT(params->eval.w) / tw);
1932 efl_canvas_object_scale_set(ep->object, s);
1933 efl_canvas_text_size_native_get(ep->object, NULL, NULL);
1934 }
1935 }
1936 if (chosen_desc->text.fit_y)
1937 {
1938 if (th > 0)
1939 {
1940 double tmp_s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s,
1941 orig_s * TO_INT(params->eval.h) / th);
1942 /* If we already have X fit, restrict Y to be no bigger
1943 * than what we got with X. */
1944 if (!((chosen_desc->text.fit_x) && (tmp_s > s)))
1945 {
1946 s = tmp_s;
1947 }
1948
1949 efl_canvas_object_scale_set(ep->object, s);
1950 efl_canvas_text_size_native_get(ep->object, NULL, NULL);
1951 }
1952 }
1953
1954 /* Final tuning, try going down 90% at a time, hoping it'll
1955 * actually end up being correct. */
1956 {
1957 int i = 5; /* Tries before we give up. */
1958 Evas_Coord fw, fh;
1959 efl_canvas_text_size_native_get(ep->object, &fw, &fh);
1960
1961 /* If we are still too big, try reducing the size to
1962 * 95% each try. */
1963 while ((i > 0) &&
1964 ((chosen_desc->text.fit_x && (fw > TO_INT(params->eval.w))) ||
1965 (chosen_desc->text.fit_y && (fh > TO_INT(params->eval.h)))))
1966 {
1967 double tmp_s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s, s * 0.95);
1968
1969 /* Break if we are not making any progress. */
1970 if (EQ(tmp_s, s))
1971 break;
1972 s = tmp_s;
1973
1974 efl_canvas_object_scale_set(ep->object, s);
1975 efl_canvas_text_size_native_get(ep->object, &fw, &fh);
1976 i--;
1977 }
1978 }
1979 }
1980
1981 if (stl)
1982 {
1983 if (evas_object_textblock_style_get(ep->object) != stl->style)
1984 evas_object_textblock_style_set(ep->object, stl->style);
1985 // FIXME: need to account for editing
1986 if (ep->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1987 {
1988 // do nothing - should be done elsewhere
1989 }
1990 else
1991 {
1992 evas_object_textblock_text_markup_set(ep->object, text);
1993 }
1994
1995 if ((ed->file->efl_version.major >= 1) && (ed->file->efl_version.minor >= 19))
1996 {
1997 _edje_part_recalc_single_textblock_min_max_calc(ep,
1998 chosen_desc,
1999 params,
2000 minw, minh,
2001 maxw, maxh);
2002 }
2003 else
2004 {
2005 _edje_part_recalc_single_textblock_min_max_calc_legacy(ep,
2006 chosen_desc,
2007 params,
2008 minw, minh,
2009 maxw, maxh);
2010 }
2011 }
2012
2013 evas_object_textblock_valign_set(ep->object, TO_DOUBLE(chosen_desc->text.align.y));
2014 }
2015}
2016
2017static void
2018_edje_textblock_recalc_apply(Edje *ed, Edje_Real_Part *ep,
2019 Edje_Calc_Params *params,
2020 Edje_Part_Description_Text *chosen_desc)
2021{
2022 /* FIXME: this is just an hack. */
2023 FLOAT_T sc;
2024 sc = DIV(ed->scale, ed->file->base_scale);
2025 if (EQ(sc, ZERO)) sc = DIV(_edje_scale, ed->file->base_scale);
2026 if (chosen_desc->text.fit_x || chosen_desc->text.fit_y)
2027 {
2028 _edje_part_recalc_single_textblock(sc, ed, ep, chosen_desc, params,
2029 NULL, NULL, NULL, NULL);
2030 }
2031}
2032
2033static void 1456static void
2034_edje_part_recalc_single_text(FLOAT_T sc EINA_UNUSED, 1457_edje_part_recalc_single_text(FLOAT_T sc EINA_UNUSED,
2035 Edje *ed, 1458 Edje *ed,
diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h
index 5c6b7a629d..9f4d07ecab 100644
--- a/src/lib/edje/edje_private.h
+++ b/src/lib/edje/edje_private.h
@@ -2548,6 +2548,18 @@ const char * _edje_text_class_font_get(Edje *ed,
2548const char * _edje_text_font_get(const char *base, const char *new, 2548const char * _edje_text_font_get(const char *base, const char *new,
2549 char **free_later); 2549 char **free_later);
2550 2550
2551void
2552_edje_part_recalc_single_textblock(FLOAT_T sc,
2553 Edje *ed,
2554 Edje_Real_Part *ep,
2555 Edje_Part_Description_Text *chosen_desc,
2556 Edje_Calc_Params *params,
2557 int *minw, int *minh,
2558 int *maxw, int *maxh);
2559void
2560_edje_textblock_recalc_apply(Edje *ed, Edje_Real_Part *ep,
2561 Edje_Calc_Params *params,
2562 Edje_Part_Description_Text *chosen_desc);
2551 2563
2552 2564
2553Edje_Real_Part *_edje_real_part_get(const Edje *ed, const char *part); 2565Edje_Real_Part *_edje_real_part_get(const Edje *ed, const char *part);
diff --git a/src/lib/edje/edje_textblock.c b/src/lib/edje/edje_textblock.c
new file mode 100644
index 0000000000..0451099fa4
--- /dev/null
+++ b/src/lib/edje/edje_textblock.c
@@ -0,0 +1,583 @@
1#include "edje_private.h"
2
3static double
4_edje_part_recalc_single_textblock_scale_range_adjust(Edje_Part_Description_Text *chosen_desc, double base_scale, double scale)
5{
6 double size, min, max;
7
8 if (chosen_desc->text.size == 0)
9 return scale;
10
11 min = base_scale * chosen_desc->text.size_range_min;
12 max = chosen_desc->text.size_range_max * base_scale;
13 size = chosen_desc->text.size * scale;
14
15 if ((size > max) && (max > 0))
16 scale = max / (double)chosen_desc->text.size;
17 else if (size < min)
18 scale = min / (double)chosen_desc->text.size;
19
20 return scale;
21}
22
23/*
24 * Legacy function for min/max calculation of textblock part.
25 * It can't calculate min/max properly in many cases.
26 *
27 * To keep backward compatibility, it will be used for old version of EDJ files.
28 * You can't see proper min/max result accroding to documents with this function.
29 */
30static void
31_edje_part_recalc_single_textblock_min_max_calc_legacy(Edje_Real_Part *ep,
32 Edje_Part_Description_Text *chosen_desc,
33 Edje_Calc_Params *params,
34 int *minw, int *minh,
35 int *maxw, int *maxh)
36{
37 Evas_Coord tw, th, ins_l, ins_r, ins_t, ins_b;
38
39 /* Legacy code for Textblock min/max calculation */
40 if ((chosen_desc->text.min_x) || (chosen_desc->text.min_y))
41 {
42 int mw = 0, mh = 0;
43
44 tw = th = 0;
45 if (!chosen_desc->text.min_x)
46 {
47 efl_gfx_size_set(ep->object, EINA_SIZE2D(TO_INT(params->eval.w), TO_INT(params->eval.h)));
48 efl_canvas_text_size_formatted_get(ep->object, &tw, &th);
49 }
50 else
51 evas_object_textblock_size_native_get(ep->object, &tw, &th);
52 evas_object_textblock_style_insets_get(ep->object, &ins_l,
53 &ins_r, &ins_t, &ins_b);
54 mw = ins_l + tw + ins_r;
55 mh = ins_t + th + ins_b;
56 if (minw && chosen_desc->text.min_x)
57 {
58 if (mw > *minw) *minw = mw;
59 }
60 if (minh && chosen_desc->text.min_y)
61 {
62 if (mh > *minh) *minh = mh;
63 }
64 }
65
66 if ((chosen_desc->text.max_x) || (chosen_desc->text.max_y))
67 {
68 int mw = 0, mh = 0;
69
70 tw = th = 0;
71 if (!chosen_desc->text.max_x)
72 {
73 efl_gfx_size_set(ep->object, EINA_SIZE2D(TO_INT(params->eval.w), TO_INT(params->eval.h)));
74 efl_canvas_text_size_formatted_get(ep->object, &tw, &th);
75 }
76 else
77 evas_object_textblock_size_native_get(ep->object, &tw, &th);
78 evas_object_textblock_style_insets_get(ep->object, &ins_l, &ins_r,
79 &ins_t, &ins_b);
80 mw = ins_l + tw + ins_r;
81 mh = ins_t + th + ins_b;
82 if (maxw && chosen_desc->text.max_x)
83 {
84 if (mw > *maxw) *maxw = mw;
85 if (minw && (*maxw < *minw)) *maxw = *minw;
86 }
87 if (maxh && chosen_desc->text.max_y)
88 {
89 if (mh > *maxh) *maxh = mh;
90 if (minh && (*maxh < *minh)) *maxh = *minh;
91 }
92 }
93}
94
95static void
96_edje_part_recalc_single_textblock_min_max_calc(Edje_Real_Part *ep,
97 Edje_Part_Description_Text *chosen_desc,
98 Edje_Calc_Params *params,
99 int *minw, int *minh,
100 int *maxw, int *maxh)
101{
102 Evas_Coord tw, th, ins_l, ins_r, ins_t, ins_b;
103 Evas_Coord min_calc_w = 0, min_calc_h = 0;
104
105 /* min_calc_* values need to save calculated minumum size
106 * for maximum size calculation */
107 if (minw) min_calc_w = *minw;
108 if (minh) min_calc_h = *minh;
109
110 if ((chosen_desc->text.min_x) || (chosen_desc->text.min_y))
111 {
112 evas_object_textblock_style_insets_get(ep->object, &ins_l,
113 &ins_r, &ins_t, &ins_b);
114
115 tw = th = 0;
116 if (!chosen_desc->text.min_x)
117 {
118 /* text.min: 0 1
119 * text.max: X X */
120 int temp_h = TO_INT(params->eval.h);
121 int temp_w = TO_INT(params->eval.w);
122
123 if (min_calc_w > temp_w)
124 temp_w = min_calc_w;
125 if ((!chosen_desc->text.max_x) &&
126 maxw && (*maxw > -1) && (*maxw < temp_w))
127 temp_w = *maxw;
128
129 if (chosen_desc->text.max_y)
130 {
131 /* text.min: 0 1
132 * text.max: X 1 */
133 temp_h = INT_MAX / 10000;
134 }
135 else if (maxh && (*maxh > TO_INT(params->eval.h)))
136 {
137 /* text.min: 0 1
138 * text.max: X 0
139 * And there is a limit for height. */
140 temp_h = *maxh;
141 }
142
143 /* If base width for calculation is 0,
144 * don't get meaningless height for multiline */
145 if (temp_w > 0)
146 {
147 efl_gfx_size_set(ep->object, EINA_SIZE2D(temp_w, temp_h));
148 efl_canvas_text_size_formatted_get(ep->object, &tw, &th);
149
150 tw += ins_l + ins_r;
151 th += ins_t + ins_b;
152 }
153 else
154 {
155 efl_canvas_text_size_native_get(ep->object, NULL, &th);
156
157 th += ins_t + ins_b;
158 }
159 }
160 else
161 {
162 /* text.min: 1 X
163 * text.max: X X */
164 if (chosen_desc->text.min_y && (!chosen_desc->text.max_x) &&
165 maxw && (*maxw > -1))
166 {
167 /* text.min: 1 1
168 * text.max: 0 X */
169 int temp_w, temp_h;
170
171 temp_w = *maxw;
172 temp_h = INT_MAX / 10000;
173
174 if (min_calc_w > temp_w)
175 temp_w = min_calc_w;
176
177 if ((!chosen_desc->text.max_y) && maxh && (*maxh > -1))
178 {
179 /* text.min: 1 1
180 * text.max: 0 0
181 * There is limit for height. */
182 temp_h = *maxh;
183 }
184
185 efl_gfx_size_set(ep->object, EINA_SIZE2D(temp_w, temp_h));
186 efl_canvas_text_size_formatted_get(ep->object, &tw, &th);
187
188 tw += ins_l + ins_r;
189 th += ins_t + ins_b;
190
191 /* If base width for calculation is 0,
192 * don't get meaningless height for multiline */
193 if (temp_w <= 0)
194 {
195 efl_canvas_text_size_native_get(ep->object, NULL, &th);
196
197 th += ins_t + ins_b;
198 }
199 }
200 else
201 {
202 /* text.min: 1 X
203 * text.max: 1 X
204 * Or,
205 * text.min: 1 X
206 * text.max: 0 X without max width.
207 * It is a singleline Textblock. */
208 efl_canvas_text_size_native_get(ep->object, &tw, &th);
209
210 tw += ins_l + ins_r;
211 th += ins_t + ins_b;
212
213 if (!chosen_desc->text.max_x &&
214 (maxw && (*maxw > -1) && (*maxw < tw)))
215 {
216 /* text.min: 1 0
217 * text.max: 0 X */
218 tw = *maxw;
219 }
220 }
221 }
222
223 if (tw > min_calc_w) min_calc_w = tw;
224 if (th > min_calc_h) min_calc_h = th;
225 if (chosen_desc->text.min_x && minw) *minw = min_calc_w;
226 if (chosen_desc->text.min_y && minh) *minh = min_calc_h;
227 }
228
229 if ((chosen_desc->text.max_x) || (chosen_desc->text.max_y))
230 {
231 evas_object_textblock_style_insets_get(ep->object, &ins_l, &ins_r,
232 &ins_t, &ins_b);
233
234 tw = th = 0;
235 if (!chosen_desc->text.max_x)
236 {
237 /* text.min: X X
238 * text.max: 0 1 */
239 int temp_w, temp_h;
240
241 if (chosen_desc->text.min_y)
242 {
243 /* text.min: X 1
244 * text.max: 0 1
245 * Already calculated in text for height. */
246 tw = TO_INT(params->eval.w);
247 if (min_calc_w > tw)
248 tw = min_calc_w;
249
250 th = min_calc_h;
251 }
252 else
253 {
254 /* text.min: X 0
255 * text.max: 0 1 */
256 temp_w = TO_INT(params->eval.w);
257 temp_h = TO_INT(params->eval.h);
258
259 if (min_calc_w > temp_w)
260 temp_w = min_calc_w;
261 if (maxw && (*maxw > -1) && (*maxw < temp_w))
262 temp_w = *maxw;
263 if (min_calc_h > temp_h)
264 temp_h = min_calc_h;
265
266 /* If base width for calculation is 0,
267 * don't get meaningless height for multiline */
268 if (temp_w > 0)
269 {
270 efl_gfx_size_set(ep->object, EINA_SIZE2D(temp_w, temp_h));
271 efl_canvas_text_size_formatted_get(ep->object, &tw, &th);
272
273 tw += ins_l + ins_r;
274 th += ins_t + ins_b;
275 }
276 else
277 {
278 efl_canvas_text_size_native_get(ep->object, NULL, &th);
279
280 th += ins_t + ins_b;
281 }
282 }
283 }
284 else
285 {
286 /* text.max: 1 X */
287 if (chosen_desc->text.min_x)
288 {
289 /* text.min: 1 X
290 * text.max: 1 X
291 * Singleline. */
292 efl_canvas_text_size_native_get(ep->object, &tw, &th);
293
294 tw += ins_l + ins_r;
295 th += ins_t + ins_b;
296 }
297 else
298 {
299 /* text.min: 0 X
300 * text.max: 1 X */
301 if (chosen_desc->text.max_y)
302 {
303 /* text.min: 0 X
304 * text.max: 1 1 */
305 int temp_w, temp_h;
306
307 temp_w = TO_INT(params->eval.w);
308 temp_h = TO_INT(params->eval.h);
309
310 if (min_calc_w > temp_w)
311 temp_w = min_calc_w;
312 if (min_calc_h > temp_h)
313 temp_h = min_calc_h;
314
315 if (chosen_desc->text.min_y)
316 {
317 /* text.min: 0 1
318 * text.max: 1 1
319 * There is no need to calculate it again. */
320 tw = min_calc_w;
321 th = min_calc_h;
322 }
323 else
324 {
325 /* text.min: 0 0
326 * text.max: 1 1 */
327
328 efl_gfx_size_set(ep->object, EINA_SIZE2D(temp_w, temp_h));
329 efl_canvas_text_size_formatted_get(ep->object, &tw, &th);
330
331 tw += ins_l + ins_r;
332 th += ins_t + ins_b;
333
334 /* If base width for calculation is 0,
335 * don't get meaningless height for multiline */
336 if (temp_w <= 0)
337 {
338 efl_canvas_text_size_native_get(ep->object, NULL, &th);
339
340 th += ins_t + ins_b;
341 }
342 }
343 }
344 else
345 {
346 /* text.min: 0 X
347 * text.max: 1 0 */
348 int temp_w, temp_h;
349
350 temp_w = TO_INT(params->eval.w);
351 if (min_calc_w > temp_w)
352 temp_w = min_calc_w;
353
354 temp_h = efl_gfx_size_get(ep->object).h;
355 efl_gfx_size_set(ep->object, EINA_SIZE2D(temp_w, temp_h));
356 efl_canvas_text_size_formatted_get(ep->object, &tw, &th);
357
358 tw += ins_l + ins_r;
359 th += ins_t + ins_b;
360
361 /* If base width for calculation is 0,
362 * don't get meaningless height for multiline */
363 if (temp_w <= 0)
364 {
365 efl_canvas_text_size_native_get(ep->object, NULL, &th);
366
367 th += ins_t + ins_b;
368 }
369 }
370 }
371 }
372
373 if (maxw && chosen_desc->text.max_x)
374 {
375 if (tw > *maxw) *maxw = tw;
376 if (minw && (*maxw < *minw)) *maxw = *minw;
377 }
378 if (maxh && chosen_desc->text.max_y)
379 {
380 if (th > *maxh) *maxh = th;
381 if (minh && (*maxh < *minh)) *maxh = *minh;
382 }
383 }
384}
385
386void
387_edje_part_recalc_single_textblock(FLOAT_T sc,
388 Edje *ed,
389 Edje_Real_Part *ep,
390 Edje_Part_Description_Text *chosen_desc,
391 Edje_Calc_Params *params,
392 int *minw, int *minh,
393 int *maxw, int *maxh)
394{
395 if ((ep->type != EDJE_RP_TYPE_TEXT) ||
396 (!ep->typedata.text))
397 return;
398
399 if (chosen_desc)
400 {
401 Evas_Coord tw, th;
402 const char *text = "";
403 const char *style = "";
404 Edje_Style *stl = NULL;
405 const char *tmp;
406 Eina_List *l;
407
408 if (chosen_desc->text.id_source >= 0)
409 {
410 Edje_Part_Description_Text *et;
411
412 ep->typedata.text->source = ed->table_parts[chosen_desc->text.id_source % ed->table_parts_size];
413
414 et = _edje_real_part_text_source_description_get(ep, NULL);
415 tmp = edje_string_get(&et->text.style);
416 if (tmp) style = tmp;
417 }
418 else
419 {
420 ep->typedata.text->source = NULL;
421
422 tmp = edje_string_get(&chosen_desc->text.style);
423 if (tmp) style = tmp;
424 }
425
426 if (chosen_desc->text.id_text_source >= 0)
427 {
428 Edje_Part_Description_Text *et;
429 Edje_Real_Part *rp;
430
431 ep->typedata.text->text_source = ed->table_parts[chosen_desc->text.id_text_source % ed->table_parts_size];
432
433 et = _edje_real_part_text_text_source_description_get(ep, &rp);
434 text = edje_string_get(&et->text.text);
435
436 if (rp->typedata.text->text) text = rp->typedata.text->text;
437 }
438 else
439 {
440 ep->typedata.text->text_source = NULL;
441 text = edje_string_get(&chosen_desc->text.text);
442 if (ep->typedata.text->text) text = ep->typedata.text->text;
443 }
444
445 EINA_LIST_FOREACH(ed->file->styles, l, stl)
446 {
447 if ((stl->name) && (!strcmp(stl->name, style))) break;
448 stl = NULL;
449 }
450
451 if (ep->part->scale)
452 evas_object_scale_set(ep->object, TO_DOUBLE(sc));
453
454 if ((chosen_desc->text.fit_x) || (chosen_desc->text.fit_y))
455 {
456 double base_s = 1.0;
457 double orig_s;
458 double s = base_s;
459
460 if (ep->part->scale) base_s = TO_DOUBLE(sc);
461 efl_canvas_object_scale_set(ep->object, base_s);
462 efl_canvas_text_size_native_get(ep->object, &tw, &th);
463
464 orig_s = base_s;
465 /* Now make it bigger so calculations will be more accurate
466 * and less influenced by hinting... */
467 {
468 orig_s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s,
469 orig_s * TO_INT(params->eval.w) / tw);
470 efl_canvas_object_scale_set(ep->object, orig_s);
471 efl_canvas_text_size_native_get(ep->object, &tw, &th);
472 }
473 if (chosen_desc->text.fit_x)
474 {
475 if (tw > 0)
476 {
477 s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s,
478 orig_s * TO_INT(params->eval.w) / tw);
479 efl_canvas_object_scale_set(ep->object, s);
480 efl_canvas_text_size_native_get(ep->object, NULL, NULL);
481 }
482 }
483 if (chosen_desc->text.fit_y)
484 {
485 if (th > 0)
486 {
487 double tmp_s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s,
488 orig_s * TO_INT(params->eval.h) / th);
489 /* If we already have X fit, restrict Y to be no bigger
490 * than what we got with X. */
491 if (!((chosen_desc->text.fit_x) && (tmp_s > s)))
492 {
493 s = tmp_s;
494 }
495
496 efl_canvas_object_scale_set(ep->object, s);
497 efl_canvas_text_size_native_get(ep->object, NULL, NULL);
498 }
499 }
500
501 /* Final tuning, try going down 90% at a time, hoping it'll
502 * actually end up being correct. */
503 {
504 int i = 5; /* Tries before we give up. */
505 Evas_Coord fw, fh;
506 efl_canvas_text_size_native_get(ep->object, &fw, &fh);
507
508 /* If we are still too big, try reducing the size to
509 * 95% each try. */
510 while ((i > 0) &&
511 ((chosen_desc->text.fit_x && (fw > TO_INT(params->eval.w))) ||
512 (chosen_desc->text.fit_y && (fh > TO_INT(params->eval.h)))))
513 {
514 double tmp_s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s, s * 0.95);
515
516 /* Break if we are not making any progress. */
517 if (EQ(tmp_s, s))
518 break;
519 s = tmp_s;
520
521 efl_canvas_object_scale_set(ep->object, s);
522 efl_canvas_text_size_native_get(ep->object, &fw, &fh);
523 i--;
524 }
525 }
526 }
527
528 if (stl)
529 {
530 if (evas_object_textblock_style_get(ep->object) != stl->style)
531 evas_object_textblock_style_set(ep->object, stl->style);
532 // FIXME: need to account for editing
533 if (ep->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
534 {
535 // do nothing - should be done elsewhere
536 }
537 else
538 {
539 evas_object_textblock_text_markup_set(ep->object, text);
540 }
541
542 if ((ed->file->efl_version.major >= 1) && (ed->file->efl_version.minor >= 19))
543 {
544 _edje_part_recalc_single_textblock_min_max_calc(ep,
545 chosen_desc,
546 params,
547 minw, minh,
548 maxw, maxh);
549 }
550 else
551 {
552 _edje_part_recalc_single_textblock_min_max_calc_legacy(ep,
553 chosen_desc,
554 params,
555 minw, minh,
556 maxw, maxh);
557 }
558 }
559
560 evas_object_textblock_valign_set(ep->object, TO_DOUBLE(chosen_desc->text.align.y));
561 }
562}
563
564void
565_edje_textblock_recalc_apply(Edje *ed, Edje_Real_Part *ep,
566 Edje_Calc_Params *params,
567 Edje_Part_Description_Text *chosen_desc)
568{
569 /* FIXME: this is just an hack. */
570 FLOAT_T sc;
571
572#if 0
573 _get_text(ep);
574#endif
575
576 sc = DIV(ed->scale, ed->file->base_scale);
577 if (EQ(sc, ZERO)) sc = DIV(_edje_scale, ed->file->base_scale);
578 if (chosen_desc->text.fit_x || chosen_desc->text.fit_y)
579 {
580 _edje_part_recalc_single_textblock(sc, ed, ep, chosen_desc, params,
581 NULL, NULL, NULL, NULL);
582 }
583}