~oem-solutions-group/unity-2d/clutter-1.0

« back to all changes in this revision

Viewing changes to clutter/clutter-units.c

  • Committer: Bazaar Package Importer
  • Author(s): Emilio Pozuelo Monfort
  • Date: 2010-03-21 13:27:56 UTC
  • mto: (2.1.3 experimental)
  • mto: This revision was merged to the branch mainline in revision 8.
  • Revision ID: james.westby@ubuntu.com-20100321132756-nf8yd30yxo3zzwcm
Tags: upstream-1.2.2
ImportĀ upstreamĀ versionĀ 1.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 * Lesser General Public License for more details.
21
21
 *
22
22
 * You should have received a copy of the GNU Lesser General Public
23
 
 * License along with this library; if not, write to the
24
 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25
 
 * Boston, MA 02111-1307, USA.
 
23
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 
24
 *
 
25
 *
26
26
 */
27
27
 
28
28
/**
71
71
 
72
72
#include "clutter-units.h"
73
73
#include "clutter-private.h"
 
74
#include "clutter-interval.h"
74
75
 
75
76
#define DPI_FALLBACK    (96.0)
76
77
 
91
92
}
92
93
 
93
94
static gfloat
 
95
units_cm_to_pixels (gfloat cm)
 
96
{
 
97
  return units_mm_to_pixels (cm * 10);
 
98
}
 
99
 
 
100
static gfloat
94
101
units_pt_to_pixels (gfloat pt)
95
102
{
96
103
  ClutterBackend *backend;
144
151
clutter_units_from_mm (ClutterUnits *units,
145
152
                       gfloat        mm)
146
153
{
 
154
  ClutterBackend *backend;
 
155
 
147
156
  g_return_if_fail (units != NULL);
148
157
 
 
158
  backend = clutter_get_default_backend ();
 
159
 
149
160
  units->unit_type  = CLUTTER_UNIT_MM;
150
161
  units->value      = mm;
151
162
  units->pixels     = units_mm_to_pixels (mm);
152
163
  units->pixels_set = TRUE;
 
164
  units->serial     = _clutter_backend_get_units_serial (backend);
 
165
}
 
166
 
 
167
/**
 
168
 * clutter_units_from_cm:
 
169
 * @units: a #ClutterUnits
 
170
 * @cm: centimeters
 
171
 *
 
172
 * Stores a value in centimeters inside @units
 
173
 *
 
174
 * Since: 1.2
 
175
 */
 
176
void
 
177
clutter_units_from_cm (ClutterUnits *units,
 
178
                       gfloat        cm)
 
179
{
 
180
  ClutterBackend *backend;
 
181
 
 
182
  g_return_if_fail (units != NULL);
 
183
 
 
184
  backend = clutter_get_default_backend ();
 
185
 
 
186
  units->unit_type  = CLUTTER_UNIT_CM;
 
187
  units->value      = cm;
 
188
  units->pixels     = units_cm_to_pixels (cm);
 
189
  units->pixels_set = TRUE;
 
190
  units->serial     = _clutter_backend_get_units_serial (backend);
153
191
}
154
192
 
155
193
/**
165
203
clutter_units_from_pt (ClutterUnits *units,
166
204
                       gfloat        pt)
167
205
{
 
206
  ClutterBackend *backend;
 
207
 
168
208
  g_return_if_fail (units != NULL);
169
209
 
 
210
  backend = clutter_get_default_backend ();
 
211
 
170
212
  units->unit_type  = CLUTTER_UNIT_POINT;
171
213
  units->value      = pt;
172
214
  units->pixels     = units_pt_to_pixels (pt);
173
215
  units->pixels_set = TRUE;
 
216
  units->serial     = _clutter_backend_get_units_serial (backend);
174
217
}
175
218
 
176
219
/**
187
230
clutter_units_from_em (ClutterUnits *units,
188
231
                       gfloat        em)
189
232
{
 
233
  ClutterBackend *backend;
 
234
 
190
235
  g_return_if_fail (units != NULL);
191
236
 
 
237
  backend = clutter_get_default_backend ();
 
238
 
192
239
  units->unit_type  = CLUTTER_UNIT_EM;
193
240
  units->value      = em;
194
241
  units->pixels     = units_em_to_pixels (NULL, em);
195
242
  units->pixels_set = TRUE;
 
243
  units->serial     = _clutter_backend_get_units_serial (backend);
196
244
}
197
245
 
198
246
/**
210
258
                                const gchar  *font_name,
211
259
                                gfloat        em)
212
260
{
 
261
  ClutterBackend *backend;
 
262
 
213
263
  g_return_if_fail (units != NULL);
214
264
 
 
265
  backend = clutter_get_default_backend ();
 
266
 
215
267
  units->unit_type  = CLUTTER_UNIT_EM;
216
268
  units->value      = em;
217
269
  units->pixels     = units_em_to_pixels (font_name, em);
218
270
  units->pixels_set = TRUE;
 
271
  units->serial     = _clutter_backend_get_units_serial (backend);
219
272
}
220
273
 
221
274
/**
231
284
clutter_units_from_pixels (ClutterUnits *units,
232
285
                           gint          px)
233
286
{
 
287
  ClutterBackend *backend;
 
288
 
234
289
  g_return_if_fail (units != NULL);
235
290
 
 
291
  backend = clutter_get_default_backend ();
 
292
 
236
293
  units->unit_type  = CLUTTER_UNIT_PIXEL;
237
294
  units->value      = px;
238
295
  units->pixels     = px;
239
296
  units->pixels_set = TRUE;
 
297
  units->serial     = _clutter_backend_get_units_serial (backend);
240
298
}
241
299
 
242
300
/**
326
384
gfloat
327
385
clutter_units_to_pixels (ClutterUnits *units)
328
386
{
 
387
  ClutterBackend *backend;
 
388
 
329
389
  g_return_val_if_fail (units != NULL, 0.0);
330
390
 
 
391
  /* if the backend settings changed we evict the cached value */
 
392
  backend = clutter_get_default_backend ();
 
393
  if (units->serial != _clutter_backend_get_units_serial (backend))
 
394
    units->pixels_set = FALSE;
 
395
 
 
396
  if (units->pixels_set)
 
397
    return units->pixels;
 
398
 
331
399
  switch (units->unit_type)
332
400
    {
333
401
    case CLUTTER_UNIT_MM:
334
402
      units->pixels = units_mm_to_pixels (units->value);
335
403
      break;
336
404
 
 
405
    case CLUTTER_UNIT_CM:
 
406
      units->pixels = units_cm_to_pixels (units->value);
 
407
      break;
 
408
 
337
409
    case CLUTTER_UNIT_POINT:
338
410
      units->pixels = units_pt_to_pixels (units->value);
339
411
      break;
348
420
    }
349
421
 
350
422
  units->pixels_set = TRUE;
 
423
  units->serial = _clutter_backend_get_units_serial (backend);
351
424
 
352
425
  return units->pixels;
353
426
}
362
435
 * A #ClutterUnits expressed in string should match:
363
436
 *
364
437
 * |[
365
 
 *   number: [0-9]
366
 
 *   unit_value: &lt;number&gt;+
367
 
 *   unit_name: px|pt|mm|em
368
 
 *   units: &lt;unit_value&gt; &lt;unit_name&gt;
 
438
 *   units: wsp* unit-value wsp* unit-name? wsp*
 
439
 *   unit-value: number
 
440
 *   unit-name: 'px' | 'pt' | 'mm' | 'em' | 'cm'
 
441
 *   number: digit+
 
442
 *           | digit* sep digit+
 
443
 *   sep: '.' | ','
 
444
 *   digit: '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
 
445
 *   wsp: (#0x20 | #0x9 | #0xA | #0xB | #0xC | #0xD)+
369
446
 * ]|
370
447
 *
371
448
 * For instance, these are valid strings:
375
452
 *   5.1 em
376
453
 *   24 pt
377
454
 *   12.6 mm
 
455
 *   .3 cm
378
456
 * ]|
379
457
 *
380
458
 * While these are not:
395
473
clutter_units_from_string (ClutterUnits *units,
396
474
                           const gchar  *str)
397
475
{
 
476
  ClutterBackend *backend;
398
477
  ClutterUnitType unit_type;
399
478
  gfloat value;
400
479
 
401
480
  g_return_val_if_fail (units != NULL, FALSE);
402
481
  g_return_val_if_fail (str != NULL, FALSE);
403
482
 
404
 
  /* Ensure that the first character is a digit */
 
483
  /* strip leading space */
405
484
  while (g_ascii_isspace (*str))
406
485
    str++;
407
486
 
408
487
  if (*str == '\0')
409
488
    return FALSE;
410
489
 
411
 
  if (!g_ascii_isdigit (*str))
412
 
    return FALSE;
413
 
 
414
490
  /* integer part */
415
491
  value = (gfloat) strtoul (str, (char **) &str, 10);
416
492
 
417
493
  if (*str == '.' || *str == ',')
418
494
    {
419
 
      glong frac = 100000;
420
 
 
421
 
      while (g_ascii_isdigit (*++str))
 
495
      gfloat divisor = 0.1;
 
496
 
 
497
      /* 5.cm is not a valid number */
 
498
      if (!g_ascii_isdigit (*++str))
 
499
        return FALSE;
 
500
 
 
501
      while (g_ascii_isdigit (*str))
422
502
        {
423
 
          frac += (*str - '0') * frac;
424
 
          frac /= 10;
 
503
          value += (*str - '0') * divisor;
 
504
          divisor *= 0.1;
 
505
          str++;
425
506
        }
426
 
 
427
 
      value += (1.0f / (gfloat) frac);
428
507
    }
429
508
 
 
509
  while (g_ascii_isspace (*str))
 
510
    str++;
 
511
 
430
512
  /* assume pixels by default, if no unit is specified */
431
 
  if (str == '\0')
 
513
  if (*str == '\0')
432
514
    unit_type = CLUTTER_UNIT_PIXEL;
 
515
  else if (strncmp (str, "em", 2) == 0)
 
516
    {
 
517
      unit_type = CLUTTER_UNIT_EM;
 
518
      str += 2;
 
519
    }
 
520
  else if (strncmp (str, "mm", 2) == 0)
 
521
    {
 
522
      unit_type = CLUTTER_UNIT_MM;
 
523
      str += 2;
 
524
    }
 
525
  else if (strncmp (str, "cm", 2) == 0)
 
526
    {
 
527
      unit_type = CLUTTER_UNIT_CM;
 
528
      str += 2;
 
529
    }
 
530
  else if (strncmp (str, "pt", 2) == 0)
 
531
    {
 
532
      unit_type = CLUTTER_UNIT_POINT;
 
533
      str += 2;
 
534
    }
 
535
  else if (strncmp (str, "px", 2) == 0)
 
536
    {
 
537
      unit_type = CLUTTER_UNIT_PIXEL;
 
538
      str += 2;
 
539
    }
433
540
  else
434
 
    {
435
 
      while (g_ascii_isspace (*str))
436
 
        str++;
437
 
 
438
 
      if (strncmp (str, "em", 2) == 0)
439
 
        unit_type = CLUTTER_UNIT_EM;
440
 
      else if (strncmp (str, "mm", 2) == 0)
441
 
        unit_type = CLUTTER_UNIT_MM;
442
 
      else if (strncmp (str, "pt", 2) == 0)
443
 
        unit_type = CLUTTER_UNIT_POINT;
444
 
      else if (strncmp (str, "px", 2) == 0)
445
 
        unit_type = CLUTTER_UNIT_PIXEL;
446
 
      else
447
541
        return FALSE;
448
 
    }
 
542
 
 
543
  /* ensure the unit is only followed by white space */
 
544
  while (g_ascii_isspace (*str))
 
545
    str++;
 
546
  if (*str != '\0')
 
547
    return FALSE;
 
548
 
 
549
  backend = clutter_get_default_backend ();
449
550
 
450
551
  units->unit_type = unit_type;
451
552
  units->value = value;
452
553
  units->pixels_set = FALSE;
 
554
  units->serial = _clutter_backend_get_units_serial (backend);
453
555
 
454
556
  return TRUE;
455
557
}
462
564
    case CLUTTER_UNIT_MM:
463
565
      return "mm";
464
566
 
 
567
    case CLUTTER_UNIT_CM:
 
568
      return "cm";
 
569
 
465
570
    case CLUTTER_UNIT_POINT:
466
571
      return "pt";
467
572
 
487
592
 * examples of output
488
593
 *
489
594
 * <note>Fractional values are truncated to the second decimal
490
 
 * position for em and mm, and to the first decimal position for
 
595
 * position for em, mm and cm, and to the first decimal position for
491
596
 * typographic points. Pixels are integers.</note>
492
597
 *
493
598
 * Return value: a newly allocated string containing the encoded
517
622
      fmt = "%.2f";
518
623
      break;
519
624
 
 
625
    case CLUTTER_UNIT_CM:
 
626
      unit_name = "cm";
 
627
      fmt = "%.2f";
 
628
      break;
 
629
 
520
630
    case CLUTTER_UNIT_POINT:
521
631
      unit_name = "pt";
522
632
      fmt = "%.1f";
538
648
}
539
649
 
540
650
/*
 
651
 * ClutterInterval integration
 
652
 */
 
653
 
 
654
static gboolean
 
655
clutter_units_progress (const GValue *a,
 
656
                        const GValue *b,
 
657
                        gdouble       progress,
 
658
                        GValue       *retval)
 
659
{
 
660
  ClutterUnits *a_units = (ClutterUnits *) clutter_value_get_units (a);
 
661
  ClutterUnits *b_units = (ClutterUnits *) clutter_value_get_units (b);
 
662
  ClutterUnits  res;
 
663
  gfloat a_px, b_px, value;
 
664
 
 
665
  a_px = clutter_units_to_pixels (a_units);
 
666
  b_px = clutter_units_to_pixels (b_units);
 
667
  value = progress * (b_px - a_px) + a_px;
 
668
 
 
669
  clutter_units_from_pixels (&res, value);
 
670
  clutter_value_set_units (retval, &res);
 
671
 
 
672
  return TRUE;
 
673
}
 
674
 
 
675
/*
541
676
 * GValue and GParamSpec integration
542
677
 */
543
678
 
622
757
      g_value_register_transform_func (G_TYPE_STRING, clutter_units_type,
623
758
                                       clutter_value_transform_string_units);
624
759
 
 
760
      clutter_interval_register_progress_func (clutter_units_type,
 
761
                                               clutter_units_progress);
 
762
 
625
763
      g_once_init_leave (&clutter_units_type__volatile, clutter_units_type);
626
764
    }
627
765
 
657
795
 * Since: 0.8
658
796
 */
659
797
G_CONST_RETURN ClutterUnits *
660
 
clutter_value_get_unit (const GValue *value)
 
798
clutter_value_get_units (const GValue *value)
661
799
{
662
800
  g_return_val_if_fail (CLUTTER_VALUE_HOLDS_UNITS (value), NULL);
663
801
 
707
845
      g_warning ("The units value of '%s' does not have the same unit "
708
846
                 "type as declared by the ClutterParamSpecUnits of '%s'",
709
847
                 str,
710
 
                 clutter_unit_type_name (otype));
 
848
                 clutter_unit_type_name (uspec->default_type));
711
849
 
712
850
      g_free (str);
713
851