<html>
    <head>
      <base href="https://bugs.freedesktop.org/" />
    </head>
    <body>
      <p>
        <div>
            <b><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - [TAGGEDPDF] Expose the structure tree and attributes in poppler-glib"
   href="https://bugs.freedesktop.org/show_bug.cgi?id=64821#c69">Comment # 69</a>
              on <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - [TAGGEDPDF] Expose the structure tree and attributes in poppler-glib"
   href="https://bugs.freedesktop.org/show_bug.cgi?id=64821">bug 64821</a>
              from <span class="vcard"><a class="email" href="mailto:carlosgc@gnome.org" title="Carlos Garcia Campos <carlosgc@gnome.org>"> <span class="fn">Carlos Garcia Campos</span></a>
</span></b>
        <pre>Comment on <span class=""><a href="attachment.cgi?id=94909" name="attach_94909" title="[PATCH v17 5/5] glib: Implement accessors for element attributes">attachment 94909</a> <a href="attachment.cgi?id=94909&action=edit" title="[PATCH v17 5/5] glib: Implement accessors for element attributes">[details]</a></span> <a href='page.cgi?id=splinter.html&bug=64821&attachment=94909'>[review]</a>
[PATCH v17 5/5] glib: Implement accessors for element attributes

Review of <span class=""><a href="attachment.cgi?id=94909" name="attach_94909" title="[PATCH v17 5/5] glib: Implement accessors for element attributes">attachment 94909</a> <a href="attachment.cgi?id=94909&action=edit" title="[PATCH v17 5/5] glib: Implement accessors for element attributes">[details]</a></span> <a href='page.cgi?id=splinter.html&bug=64821&attachment=94909'>[review]</a>:
-----------------------------------------------------------------

This looks much better now, thanks. But still have some doubts and comments

::: glib/poppler-structure-element.cc
@@ +385,5 @@
<span class="quote">> +  /*
> +   * Non-NULL names must always be valid because Poppler
> +   * discards the invalid attributes when parsing them.
> +   */
> +  g_assert (name_value != NULL);</span >

This assert is duplicated.

@@ +401,5 @@
<span class="quote">> +static EnumType
> +attr_to_enum (PopplerStructureElement *poppler_structure_element)
> +{
> +  const Attribute *attr =
> +      poppler_structure_element->elem->findAttribute (EnumNameValue<EnumType>::attribute_type, gTrue);</span >

I wonder if we should do the same for the core api, and always inherit when the
attr is inheritable.

@@ +967,5 @@
<span class="quote">>   *
> + * Obtains the #PopplerFormField out of an element of type
> + * %POPPLER_STRUCTURE_ELEMENT_FORM. The returned value must be freed
> + * with g_object_unref(). Note that there is one structure element
> + * per form field.</span >

This is unrelated to this patch.

@@ +973,4 @@
<span class="quote">>   * Return value: (transfer full): A #PopplerFormField, or %NULL if
>   *    the element is not a %POPPLER_STRUCTURE_ELEMENT_FORM.
> + *
> + * Since: 0.26</span >

Ditto.

@@ +1018,5 @@
<span class="quote">>   *
> + * Obtains the #PopplerFormField out of an element of type
> + * %POPPLER_STRUCTURE_ELEMENT_FORM. The returned value must be freed
> + * with g_object_unref(). Note that there is one structure element
> + * per form field.</span >

Ditto.

@@ +1024,4 @@
<span class="quote">>   * Return value: (transfer full): A #PopplerFormFieldMapping, or %NULL if
>   *    the element is not a %POPPLER_STRUCTURE_ELEMENT_FORM
> + *
> + * Since: 0.26</span >

Ditto.

@@ +1154,5 @@
<span class="quote">> + */
> +PopplerStructurePlacement
> +poppler_structure_element_get_placement (PopplerStructureElement *poppler_structure_element)
> +{
> +  ATTRIBUTE_GETTER_BODY (PopplerStructurePlacement);</span >

You are going too far, this is just two lines of code

@@ +1174,5 @@
<span class="quote">> +{
> +  ATTRIBUTE_GETTER_BODY (PopplerStructureWritingMode);
> +}
> +
> +</span >

Nit: Extra empty line here.

@@ +1186,5 @@
<span class="quote">> +    {
> +      g_assert (object->arrayGetLength () == 4);
> +      Object item;
> +      for (guint i = 0; i < 4; i++)
> +        values[i] = name_to_enum<PopplerStructureBorderStyle> (object->arrayGet (i, &item));</span >

I think you should item.free() everytime.

@@ +1205,5 @@
<span class="quote">> +    {
> +      g_assert (object->arrayGetLength () == 4);
> +      Object item;
> +      for (guint i = 0; i < 4; i++)
> +        value[i] = object->arrayGet (i, &item)->getNum ();</span >

Ditto.

@@ +1227,5 @@
<span class="quote">> +  gdouble* doubles = g_new (gdouble, *n_values);
> +  Object item;
> +
> +  for (guint i = 0; i < *n_values; i++)
> +    doubles[i] = object->arrayGet (i, &item)->getNum ();</span >

Ditto.

@@ +1241,5 @@
<span class="quote">> +  Object item;
> +
> +  color->red   = object->arrayGet (0, &item)->getNum () * 65535;
> +  color->green = object->arrayGet (1, &item)->getNum () * 65535;
> +  color->blue  = object->arrayGet (2, &item)->getNum () * 65535;</span >

Ditto.

@@ +1262,5 @@
<span class="quote">> + */
> +PopplerStructureBorderStyle *
> +poppler_structure_element_get_border_style (PopplerStructureElement *poppler_structure_element)
> +{
> +  g_return_val_if_fail (POPPLER_IS_STRUCTURE_ELEMENT (poppler_structure_element), NULL);</span >

Should we check also that this is called for an element than can have a border
style attr? and the same for all other attributes.

@@ +1279,5 @@
<span class="quote">> + * are in before-after-start-end ordering (for the typical Western
> + * left-to-right writing, that is top-bottom-left-right). The returned
> + * value must be freed with g_free().
> + *
> + * Return value: (transfer full) (array fixed-size=4): An array with the</span >

(element-type PopplerStructureBorderStyle)

@@ +1331,5 @@
<span class="quote">> +/**
> + * poppler_structure_element_get_inline_align:
> + * @poppler_structure_element: A #PopplerStructureElement
> + *
> + * Obtains the block-alignment mode of the structure element.</span >

next method is block_alignment

@@ +1473,5 @@
<span class="quote">> + *
> + * Since: 0.26
> + */
> +PopplerStructureChecked
> +poppler_structure_element_get_checked (PopplerStructureElement *poppler_structure_element)</span >

I also wonder if we should make more obvious that fact that some attributes are
only availble for some kinds for elements. For example, this method could be:

poppler_structure_element_form_get_state and the previous one
poppler_structure_element_form_get_role()

Also, I would rename PopplerStructureChecked as PopplerStructureFormState since
it described better what it is. In the core API we should follow the spec and
use the same names, to make it easier to follow the code reading the spec. But
in the public API we can change the exposed names when we think are better. And
this is definitely one of those cases.

@@ +1486,5 @@
<span class="quote">> + * Obtains the thickness of the border of an element. The result values
> + * are in before-after-start-end ordering (for the typical Western
> + * left-to-right writing, that is top-bottom-left-right).
> + *
> + * Return value: (transfer full) (array fixed-length=4): Thickness of</span >

(element-type gdouble)

@@ +1512,5 @@
<span class="quote">> + *
> + * Obtains the thickness of the text decoration for the text contained
> + * in the element.
> + *
> + * Return value: Thickness of the text decoration, or %NaN if not defined.</span >

Can the thickness be a negative number? I prefer to use something like -1
instead of NAN

@@ +1530,5 @@
<span class="quote">> + * poppler_structure_element_get_padding:
> + * @poppler_structure_element: A #PopplerStructureElement
> + *
> + * Obtains the padding of an element (space around it). The result
> + * values are in before-after-start-end ordering (for the typical</span >

s/typical//

@@ +1533,5 @@
<span class="quote">> + * Obtains the padding of an element (space around it). The result
> + * values are in before-after-start-end ordering (for the typical
> + * Western left-to-right writing, that is top-bottom-left-right).
> + *
> + * Return value: (transfer full) (array fixed-size=4): Padding for</span >

(element-type gdouble)

@@ +1550,5 @@
<span class="quote">> +  return result;
> +}
> +
> +/**
> + * poppler_structure_element_get_table_padding:</span >

poppler_structure_element_table_get_padding maybe?

@@ +1557,5 @@
<span class="quote">> + * Obtains the padding of an element (space around it). The result
> + * values are in before-after-start-end ordering (for the typical
> + * Western left-to-right writing, that is top-bottom-left-right).
> + * This has to be used instead of poppler_structure_element_get_padding()
> + * for table elements.</span >

If the name is what I propose, table_get_padding, I think it's more obvious
that this is used for table elements.

@@ +1559,5 @@
<span class="quote">> + * Western left-to-right writing, that is top-bottom-left-right).
> + * This has to be used instead of poppler_structure_element_get_padding()
> + * for table elements.
> + *
> + * Return value: (transfer full) (array fixed-size=4): The paddings for</span >

(element-type gdouble)

@@ +1580,5 @@
<span class="quote">> + * poppler_structure_element_get_bounding_box:
> + * @poppler_structure_element: A #PopplerStructureElement
> + *
> + * Obtains the size of the bounding box of the element. This has to be
> + * used instead of poppler_structure_element_get_padding() for table</span >

Why is this related to the padding?

@@ +1589,5 @@
<span class="quote">> + *
> + * Since: 0.26
> + */
> +PopplerRectangle *
> +poppler_structure_element_get_bounding_box (PopplerStructureElement *poppler_structure_element)</span >

This is one of the case where we could use the approach of returning a boolean
and pass a PopplerRectangle * as parameter, since that allows to use a stack
allocated rectangle.

@@ +1622,5 @@
<span class="quote">> + */
> +gdouble
> +poppler_structure_element_get_space_before (PopplerStructureElement *poppler_structure_element)
> +{
> +  g_return_val_if_fail (POPPLER_IS_STRUCTURE_ELEMENT (poppler_structure_element), NAN);</span >

-1

@@ +1639,5 @@
<span class="quote">> + */
> +gdouble
> +poppler_structure_element_get_space_after (PopplerStructureElement *poppler_structure_element)
> +{
> +  g_return_val_if_fail (POPPLER_IS_STRUCTURE_ELEMENT (poppler_structure_element), NAN);</span >

-1

@@ +1656,5 @@
<span class="quote">> + */
> +gdouble
> +poppler_structure_element_get_start_indent (PopplerStructureElement *poppler_structure_element)
> +{
> +  g_return_val_if_fail (POPPLER_IS_STRUCTURE_ELEMENT (poppler_structure_element), NAN);</span >

-1

@@ +1673,5 @@
<span class="quote">> + */
> +gdouble
> +poppler_structure_element_get_end_indent (PopplerStructureElement *poppler_structure_element)
> +{
> +  g_return_val_if_fail (POPPLER_IS_STRUCTURE_ELEMENT (poppler_structure_element), NAN);</span >

I prefer to use -1 instead of NAN everywhere.

@@ +1743,5 @@
<span class="quote">> + *
> + * Since: 0.26
> + */
> +PopplerColor *
> +poppler_structure_element_get_color (PopplerStructureElement *poppler_structure_element)</span >

This is another case where we could return boolean when not present and allow
to pass a pointer to a stack allocated color.

@@ +1768,5 @@
<span class="quote">> + *
> + * Since: 0.26
> + */
> +PopplerColor *
> +poppler_structure_element_get_background_color (PopplerStructureElement *poppler_structure_element)</span >

Ditto.

@@ +1794,5 @@
<span class="quote">> + *
> + * Since: 0.26
> + */
> +PopplerColor *
> +poppler_structure_element_get_text_decoration_color (PopplerStructureElement *poppler_structure_element)</span >

Ditto.

@@ +1856,5 @@
<span class="quote">> + *
> + * Since: 0.26
> + */
> +gdouble
> +poppler_structure_element_get_width (PopplerStructureElement *poppler_structure_element)</span >

Why not merging both functions and have a special value for auto? For example
when this returns -1 is because it's auto

@@ +1869,5 @@
<span class="quote">> + * @poppler_structure_element: A #PopplerStructureElement
> + *
> + * Check whether the width of the element is to be calculated automatically
> + * depending on its contents. Note that when the width is automatic, using
> + * poppler_structure_element_get_width() will fail.</span >

And we avoid this situation.

@@ +1908,5 @@
<span class="quote">> + * @poppler_structure_element: A #PopplerStructureElement
> + *
> + * Check whether the height of the element is to be calculated automatically
> + * depending on its contents. Note that when the height is automatic, using
> + * poppler_structure_element_get_height() will fail.</span >

Same for the height.

@@ +1949,5 @@
<span class="quote">> + *
> + * Check whether the line height for the text contained in the element is
> + * to be calculated automatically depending on the font size. Note that
> + * when the line height is automatic,
> + * poppler_structure_element_get_line_height() will fail.</span >

Same here.

@@ +1997,5 @@
<span class="quote">> +
> +  Object *value = attr_value_or_default (poppler_structure_element, Attribute::ColumnGap);
> +  if (value == NULL)
> +    {
> +      *n_values = static_cast<guint> (-1);</span >

The doc says this is set to 0, something I agree with.

@@ +2031,5 @@
<span class="quote">> +
> +  Object *value = attr_value_or_default (poppler_structure_element, Attribute::ColumnWidths);
> +  if (value == NULL)
> +    {
> +      *n_values = static_cast<guint> (-1);</span >

Return 0 here.

@@ +2063,5 @@
<span class="quote">> +poppler_structure_element_get_description (PopplerStructureElement *poppler_structure_element)
> +{
> +  g_return_val_if_fail (POPPLER_IS_STRUCTURE_ELEMENT (poppler_structure_element), NULL);
> +
> +  Object *value = attr_value_or_default (poppler_structure_element, Attribute::Desc);</span >

Who owns the returned Object? the element?

@@ +2069,5 @@
<span class="quote">> +    return NULL;
> +  if (value->isString ())
> +    return _poppler_goo_string_to_utf8 (value->getString ());
> +  if (value->isName ())
> +    return g_strdup (value->getName ());</span >

What encoding is this, we should ensure all strings returned by our api a valid
utf8

@@ +2106,5 @@
<span class="quote">> +  if (value->isString ())
> +    return _poppler_goo_string_to_utf8 (value->getString ());
> +  if (value->isName ())
> +    return g_strdup (value->getName ());
> +</span >

Same comments here.

@@ +2119,5 @@
<span class="quote">> + * Obtains the color of border around the element. The result values
> + * are in before-after-start-end ordering (for the typical Western
> + * left-to-right writing, that is top-bottom-left-right).
> + *
> + * Return value: (transfer full) (array fixed-size=4): Border colors,</span >

(element-type PopplerColor)

@@ +2141,5 @@
<span class="quote">> +    {
> +      // One color per side.
> +      Object item;
> +      for (guint i = 0; i < 4; i++)
> +        convert_color (value->arrayGet (i, &item), &result[i]);</span >

item.free() everytime

@@ +2174,5 @@
<span class="quote">> + * Since: 0.26
> + */
> +gchar **
> +poppler_structure_element_get_headers (PopplerStructureElement *poppler_structure_element,
> +                                       guint                   *n_values)</span >

We don't need this, since it's a null terminated array. You can iterate ntil
null or get the length with g_strv_length if needed

@@ +2196,5 @@
<span class="quote">> +        result[i] = _poppler_goo_string_to_utf8 (item.getString ());
> +      else if (item.isName ())
> +        result[i] = g_strdup (item.getName ());
> +      else
> +        g_assert_not_reached ();</span >

item.free() everytime</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>