Compare commits
	
		
			261 Commits
		
	
	
		
			wip/carlos
			...
			wip/lantw/
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					af0478ae1e | ||
| 
						 | 
					aedf692e0c | ||
| 
						 | 
					5dfd86ebe7 | ||
| 
						 | 
					9e41f687a0 | ||
| 
						 | 
					61356caa06 | ||
| 
						 | 
					4300f1f91d | ||
| 
						 | 
					d26dc4ae44 | ||
| 
						 | 
					bd45a00fa3 | ||
| 
						 | 
					793a9d45e1 | ||
| 
						 | 
					43295bdcc4 | ||
| 
						 | 
					43e12dab7b | ||
| 
						 | 
					c4535fdf85 | ||
| 
						 | 
					d2c3272eb7 | ||
| 
						 | 
					90c4b6492f | ||
| 
						 | 
					b7bf42e778 | ||
| 
						 | 
					e849667be6 | ||
| 
						 | 
					424016d66c | ||
| 
						 | 
					a4f55d4986 | ||
| 
						 | 
					1b33a5a3a7 | ||
| 
						 | 
					36111270aa | ||
| 
						 | 
					6e0cfd3e55 | ||
| 
						 | 
					5671f0a284 | ||
| 
						 | 
					a7e63bea6c | ||
| 
						 | 
					94b3c334e5 | ||
| 
						 | 
					efb0addb62 | ||
| 
						 | 
					988da215c8 | ||
| 
						 | 
					551a57ed7f | ||
| 
						 | 
					b7366b5b53 | ||
| 
						 | 
					5e8d8b9ade | ||
| 
						 | 
					4726f3d5d3 | ||
| 
						 | 
					91ef7515de | ||
| 
						 | 
					317f6c0910 | ||
| 
						 | 
					6a3d521466 | ||
| 
						 | 
					1363246d44 | ||
| 
						 | 
					0b6560fac4 | ||
| 
						 | 
					d4c3870286 | ||
| 
						 | 
					4bdf9a1e70 | ||
| 
						 | 
					1909977a67 | ||
| 
						 | 
					655a783891 | ||
| 
						 | 
					a4596becc4 | ||
| 
						 | 
					7015bb3efd | ||
| 
						 | 
					d2c762cc66 | ||
| 
						 | 
					04d429b743 | ||
| 
						 | 
					0b21dcfe08 | ||
| 
						 | 
					7c939d78c2 | ||
| 
						 | 
					8a2b82897d | ||
| 
						 | 
					e95c365cf0 | ||
| 
						 | 
					a32cb7133b | ||
| 
						 | 
					967966cdee | ||
| 
						 | 
					06d67b6abf | ||
| 
						 | 
					f15ce01e2b | ||
| 
						 | 
					e48516679c | ||
| 
						 | 
					65a6c4c361 | ||
| 
						 | 
					b51c468c0f | ||
| 
						 | 
					2e7d02f1ce | ||
| 
						 | 
					dc4fe780f7 | ||
| 
						 | 
					d682cdb078 | ||
| 
						 | 
					ff7a42b8bc | ||
| 
						 | 
					4b1805c306 | ||
| 
						 | 
					03c00e4944 | ||
| 
						 | 
					cb05b16414 | ||
| 
						 | 
					b9fe9c736a | ||
| 
						 | 
					3dd8861fbf | ||
| 
						 | 
					753066598f | ||
| 
						 | 
					3da8c1bfdc | ||
| 
						 | 
					f8ee974628 | ||
| 
						 | 
					f36120757f | ||
| 
						 | 
					bc178b711f | ||
| 
						 | 
					5dad87cfb9 | ||
| 
						 | 
					0f8f607e4c | ||
| 
						 | 
					282aada13a | ||
| 
						 | 
					47002bf0cd | ||
| 
						 | 
					3d47c7edc1 | ||
| 
						 | 
					bc350f37f5 | ||
| 
						 | 
					b55e2e1df9 | ||
| 
						 | 
					43baf643d4 | ||
| 
						 | 
					21b8ae10b8 | ||
| 
						 | 
					425a10de11 | ||
| 
						 | 
					d0ef660ff6 | ||
| 
						 | 
					506e06589b | ||
| 
						 | 
					1d75d5aa2f | ||
| 
						 | 
					645d596f9d | ||
| 
						 | 
					3e967d731a | ||
| 
						 | 
					167fd07e01 | ||
| 
						 | 
					fbd6366edd | ||
| 
						 | 
					23d0bdd46d | ||
| 
						 | 
					0d0834f87c | ||
| 
						 | 
					676997e0af | ||
| 
						 | 
					633d5d1b84 | ||
| 
						 | 
					f620f43353 | ||
| 
						 | 
					eb6e1f694a | ||
| 
						 | 
					6aead84d7a | ||
| 
						 | 
					5b984c1e53 | ||
| 
						 | 
					7660ca2579 | ||
| 
						 | 
					ac52631e8a | ||
| 
						 | 
					5b30a52bbd | ||
| 
						 | 
					a5294ce55f | ||
| 
						 | 
					553372ffb7 | ||
| 
						 | 
					f672d6ee3b | ||
| 
						 | 
					ba3417667f | ||
| 
						 | 
					50fa002a19 | ||
| 
						 | 
					f0718c7d95 | ||
| 
						 | 
					e74c2e42cf | ||
| 
						 | 
					ce64ab5449 | ||
| 
						 | 
					8df3b21a51 | ||
| 
						 | 
					08431a127a | ||
| 
						 | 
					3f068d1138 | ||
| 
						 | 
					6f0e5b0b56 | ||
| 
						 | 
					fe27a6ea3b | ||
| 
						 | 
					1301770dcb | ||
| 
						 | 
					1551b6d386 | ||
| 
						 | 
					a6f94696e2 | ||
| 
						 | 
					c389aadff9 | ||
| 
						 | 
					37eda498f2 | ||
| 
						 | 
					7d2df52336 | ||
| 
						 | 
					5d27e5415d | ||
| 
						 | 
					625773fba4 | ||
| 
						 | 
					7d79ae7b07 | ||
| 
						 | 
					5817779656 | ||
| 
						 | 
					5f5ce08ba4 | ||
| 
						 | 
					223f033780 | ||
| 
						 | 
					50e0ae3cf3 | ||
| 
						 | 
					a8f6cada88 | ||
| 
						 | 
					7f488e3e1d | ||
| 
						 | 
					059d2144b2 | ||
| 
						 | 
					902302a174 | ||
| 
						 | 
					f98ca7683c | ||
| 
						 | 
					479fb0549c | ||
| 
						 | 
					52e5d6fc94 | ||
| 
						 | 
					09a6031c69 | ||
| 
						 | 
					dbe919ef92 | ||
| 
						 | 
					2907ee93cc | ||
| 
						 | 
					aa136f4515 | ||
| 
						 | 
					8748841094 | ||
| 
						 | 
					86f2885e98 | ||
| 
						 | 
					bb5ea0580f | ||
| 
						 | 
					2cfdbbd730 | ||
| 
						 | 
					9f31e7252c | ||
| 
						 | 
					e8ea5ecd8a | ||
| 
						 | 
					ed10aea44d | ||
| 
						 | 
					fed5f4d9aa | ||
| 
						 | 
					73250b8f4c | ||
| 
						 | 
					f6700f19a7 | ||
| 
						 | 
					ea34915df3 | ||
| 
						 | 
					37742c5cde | ||
| 
						 | 
					cdd27d0e53 | ||
| 
						 | 
					82778f72a4 | ||
| 
						 | 
					d846fabda2 | ||
| 
						 | 
					2d94a34a14 | ||
| 
						 | 
					92710d8f89 | ||
| 
						 | 
					da600b8400 | ||
| 
						 | 
					6aa546145f | ||
| 
						 | 
					3956ffd5e8 | ||
| 
						 | 
					05341221d4 | ||
| 
						 | 
					95642d05a6 | ||
| 
						 | 
					51cd8aed96 | ||
| 
						 | 
					ac01e69a67 | ||
| 
						 | 
					a68e6972a2 | ||
| 
						 | 
					55cf1c1496 | ||
| 
						 | 
					343de21af5 | ||
| 
						 | 
					3c157242fa | ||
| 
						 | 
					32c99513c8 | ||
| 
						 | 
					40c345d6f3 | ||
| 
						 | 
					8beef8ccd0 | ||
| 
						 | 
					62d0dd907b | ||
| 
						 | 
					0462208d4e | ||
| 
						 | 
					6885c37784 | ||
| 
						 | 
					238e41d493 | ||
| 
						 | 
					8699482475 | ||
| 
						 | 
					dcaa45fc0c | ||
| 
						 | 
					3c4f5ddcb4 | ||
| 
						 | 
					3aece84499 | ||
| 
						 | 
					40fb06ca17 | ||
| 
						 | 
					d4c070da88 | ||
| 
						 | 
					d052f9c070 | ||
| 
						 | 
					3b88af94e3 | ||
| 
						 | 
					1f00aba92c | ||
| 
						 | 
					ec1195e3ff | ||
| 
						 | 
					18b661cc93 | ||
| 
						 | 
					8592a8591b | ||
| 
						 | 
					7fa7c2aeb7 | ||
| 
						 | 
					41130b08eb | ||
| 
						 | 
					1d20045247 | ||
| 
						 | 
					c131a9b7fa | ||
| 
						 | 
					2ecbf6d746 | ||
| 
						 | 
					a13d60aae5 | ||
| 
						 | 
					ed4b80cee5 | ||
| 
						 | 
					0a6034ef3a | ||
| 
						 | 
					c9a5b2b22f | ||
| 
						 | 
					db9b60cc63 | ||
| 
						 | 
					fa74da0039 | ||
| 
						 | 
					b310e1d9d7 | ||
| 
						 | 
					0053ef2e16 | ||
| 
						 | 
					4133b73632 | ||
| 
						 | 
					074f4974dd | ||
| 
						 | 
					0700f3749f | ||
| 
						 | 
					0487e6f11f | ||
| 
						 | 
					23da6c2426 | ||
| 
						 | 
					67dd0b4fec | ||
| 
						 | 
					6989fea767 | ||
| 
						 | 
					df33255162 | ||
| 
						 | 
					5319949a45 | ||
| 
						 | 
					aba0b9ef64 | ||
| 
						 | 
					512bb7d1cd | ||
| 
						 | 
					d2a12ee0fa | ||
| 
						 | 
					531a195cf1 | ||
| 
						 | 
					509e9ca5a0 | ||
| 
						 | 
					0743381573 | ||
| 
						 | 
					267f712068 | ||
| 
						 | 
					0b102afb53 | ||
| 
						 | 
					304a103659 | ||
| 
						 | 
					2d09e95934 | ||
| 
						 | 
					be11525b28 | ||
| 
						 | 
					adc38f902a | ||
| 
						 | 
					8abdf16a39 | ||
| 
						 | 
					4cc29cfb61 | ||
| 
						 | 
					121c5d2a92 | ||
| 
						 | 
					50ff30bf2b | ||
| 
						 | 
					26e1e495a0 | ||
| 
						 | 
					480e7d44be | ||
| 
						 | 
					1c1adb0036 | ||
| 
						 | 
					6b852e6cb3 | ||
| 
						 | 
					6e966e47f2 | ||
| 
						 | 
					227eea1e31 | ||
| 
						 | 
					79920d66d4 | ||
| 
						 | 
					6cd0aa429f | ||
| 
						 | 
					15d3de0099 | ||
| 
						 | 
					38fb59a6a6 | ||
| 
						 | 
					748f5bb3e6 | ||
| 
						 | 
					3c55475391 | ||
| 
						 | 
					dd6e371bac | ||
| 
						 | 
					00d900e46d | ||
| 
						 | 
					a4f11bef47 | ||
| 
						 | 
					c4f76622a6 | ||
| 
						 | 
					f80e5dd8e4 | ||
| 
						 | 
					f484efaac1 | ||
| 
						 | 
					f97804f4f4 | ||
| 
						 | 
					5c37f5104e | ||
| 
						 | 
					d08a8de265 | ||
| 
						 | 
					6c82feb1b8 | ||
| 
						 | 
					0dac91cffc | ||
| 
						 | 
					ff381d1d52 | ||
| 
						 | 
					05e9d6ab9e | ||
| 
						 | 
					d22f947bf5 | ||
| 
						 | 
					9b97e5ed58 | ||
| 
						 | 
					7f9fac2ba2 | ||
| 
						 | 
					64eaf70279 | ||
| 
						 | 
					e3149e6021 | ||
| 
						 | 
					166a464515 | ||
| 
						 | 
					38e58b837b | ||
| 
						 | 
					39a8c047d1 | ||
| 
						 | 
					c979cd95aa | ||
| 
						 | 
					6831f2edb4 | ||
| 
						 | 
					372d73e275 | ||
| 
						 | 
					0ada90024f | ||
| 
						 | 
					46e38ff61a | ||
| 
						 | 
					1e0b015ce8 | ||
| 
						 | 
					72054332c5 | ||
| 
						 | 
					d30ef0dd3b | ||
| 
						 | 
					84275688f3 | ||
| 
						 | 
					90a1eb4275 | 
@@ -1,10 +1,9 @@
 | 
			
		||||
image: registry.gitlab.gnome.org/gnome/mutter/master:v3
 | 
			
		||||
image: registry.gitlab.gnome.org/gnome/mutter/master:v4
 | 
			
		||||
 | 
			
		||||
stages:
 | 
			
		||||
 - review
 | 
			
		||||
 - build
 | 
			
		||||
 - test
 | 
			
		||||
 - analysis
 | 
			
		||||
 | 
			
		||||
check-commit-log:
 | 
			
		||||
  stage: review
 | 
			
		||||
@@ -29,6 +28,20 @@ build-mutter:
 | 
			
		||||
    - merge_requests
 | 
			
		||||
    - /^.*$/
 | 
			
		||||
 | 
			
		||||
build-without-opengl-and-glx:
 | 
			
		||||
  stage: build
 | 
			
		||||
  script:
 | 
			
		||||
    - meson . build -Dbuildtype=debugoptimized -Dopengl=false -Dglx=false -Degl_device=true -Dwayland_eglstream=true --werror --prefix /usr
 | 
			
		||||
    - ninja -C build
 | 
			
		||||
    - ninja -C build install
 | 
			
		||||
  artifacts:
 | 
			
		||||
    expire_in: 1 day
 | 
			
		||||
    paths:
 | 
			
		||||
      - build
 | 
			
		||||
  only:
 | 
			
		||||
    - merge_requests
 | 
			
		||||
    - /^.*$/
 | 
			
		||||
 | 
			
		||||
build-without-native-backend-and-wayland:
 | 
			
		||||
  stage: build
 | 
			
		||||
  script:
 | 
			
		||||
@@ -78,20 +91,3 @@ can-build-gnome-shell:
 | 
			
		||||
  only:
 | 
			
		||||
    - merge_requests
 | 
			
		||||
    - /^.*$/
 | 
			
		||||
 | 
			
		||||
coverity:
 | 
			
		||||
  stage: analysis
 | 
			
		||||
  allow_failure: true
 | 
			
		||||
  script:
 | 
			
		||||
    - dnf install -y clang
 | 
			
		||||
    - curl https://scan.coverity.com/download/linux64 --data "token=$COVERITY_TOKEN&project=mutter" --output /tmp/coverity_tool.tgz
 | 
			
		||||
    - tar zxf /tmp/coverity_tool.tgz
 | 
			
		||||
    - CC=clang meson coverity-build
 | 
			
		||||
    - ./cov-analysis-linux64-*/bin/cov-build --dir cov-int ninja -C coverity-build
 | 
			
		||||
    - tar czf cov-int.tar.gz cov-int
 | 
			
		||||
    - curl https://scan.coverity.com/builds?project=mutter
 | 
			
		||||
      --form token=$COVERITY_TOKEN --form email=carlosg@gnome.org
 | 
			
		||||
      --form file=@cov-int.tar.gz --form version="`git describe --tags`"
 | 
			
		||||
      --form description="gitlab CI build"
 | 
			
		||||
  only:
 | 
			
		||||
    - master
 | 
			
		||||
 
 | 
			
		||||
@@ -1,32 +1,27 @@
 | 
			
		||||
# Rebuild and push with
 | 
			
		||||
#
 | 
			
		||||
#     cd .gitlab-ci/
 | 
			
		||||
#     podman build --format docker --no-cache -t registry.gitlab.gnome.org/gnome/mutter/master:v3 .
 | 
			
		||||
#     podman push registry.gitlab.gnome.org/gnome/mutter/master:v3
 | 
			
		||||
#     podman build --format docker --no-cache -t registry.gitlab.gnome.org/gnome/mutter/master:v4 .
 | 
			
		||||
#     podman push registry.gitlab.gnome.org/gnome/mutter/master:v4
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
FROM fedora:31
 | 
			
		||||
FROM fedora:32
 | 
			
		||||
 | 
			
		||||
RUN dnf -y update && dnf -y upgrade && \
 | 
			
		||||
    dnf install -y 'dnf-command(builddep)' && \
 | 
			
		||||
    dnf install -y 'dnf-command(copr)' && \
 | 
			
		||||
    dnf copr enable -y fmuellner/gnome-shell-ci && \
 | 
			
		||||
    dnf copr enable -y jadahl/mutter-ci && \
 | 
			
		||||
    dnf -y update && dnf -y upgrade && \
 | 
			
		||||
 | 
			
		||||
    dnf builddep -y mutter && \
 | 
			
		||||
 | 
			
		||||
    # Until Fedora catches up with new build-deps
 | 
			
		||||
    dnf install -y 'pkgconfig(graphene-gobject-1.0)' 'pkgconfig(sysprof-capture-3)' && \
 | 
			
		||||
    dnf builddep -y mutter --setopt=install_weak_deps=False && \
 | 
			
		||||
 | 
			
		||||
    # For running unit tests
 | 
			
		||||
    dnf install -y xorg-x11-server-Xvfb mesa-dri-drivers dbus dbus-x11 '*/xvfb-run' gdm-lib accountsservice-libs gnome-control-center && \
 | 
			
		||||
    dnf install -y xorg-x11-server-Xvfb mesa-dri-drivers dbus dbus-x11 \
 | 
			
		||||
        '*/xvfb-run' gdm-lib accountsservice-libs gnome-control-center \
 | 
			
		||||
        --setopt=install_weak_deps=False && \
 | 
			
		||||
 | 
			
		||||
    # GNOME Shell
 | 
			
		||||
    dnf builddep -y gnome-shell --setopt=install_weak_deps=False && \
 | 
			
		||||
    dnf remove -y gnome-bluetooth-libs-devel dbus-glib-devel upower-devel python3-devel && \
 | 
			
		||||
    dnf remove -y gnome-bluetooth-libs-devel && \
 | 
			
		||||
    dnf remove -y --noautoremove mutter mutter-devel && \
 | 
			
		||||
 | 
			
		||||
    dnf upgrade -y 'pkgconfig(libpipewire-0.3)' && \
 | 
			
		||||
 | 
			
		||||
    dnf clean all
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										85
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										85
									
								
								NEWS
									
									
									
									
									
								
							@@ -1,3 +1,88 @@
 | 
			
		||||
3.37.1
 | 
			
		||||
======
 | 
			
		||||
* Fix screencasting non-maximized windows [Jonas Å.; !1174]
 | 
			
		||||
* Make window-aliveness checks less aggressive [Jonas Å.; !1182]
 | 
			
		||||
* Fix stylus coordinates when using screen rotation [Jonas T.; #1118]
 | 
			
		||||
* Preserve keyboard state on VT switch [Olivier; !1185]
 | 
			
		||||
* Remove Clutter's drag and drop actions [Jonas D.; !789]
 | 
			
		||||
* Cancel clicks/gestures actions on disable [Georges; !1188]
 | 
			
		||||
* Fix various clipboard issues [Carlos; !1186, !1198, !1203, !1204, !1206]
 | 
			
		||||
* Fix trackball button scrolling [Phillip; #1120]
 | 
			
		||||
* Fix tiled monitor support [Jonas; !1199]
 | 
			
		||||
* Support unredirecting fullscreen wayland surfaces [Jonas Å.; !798]
 | 
			
		||||
* Support area screencasts [Jonas Å.; !1207]
 | 
			
		||||
* Synchronize shadows to server-side decorations [Olivier; !1214]
 | 
			
		||||
* Allow inhibiting remote access [Jonas Å.; !1212]
 | 
			
		||||
* Fix overview key on X11 when using multiple keyboard layouts [Olivier; !1219]
 | 
			
		||||
* Fixed crashes [Jonas, D., Carlos; !1173, !1183, !1012]
 | 
			
		||||
* Misc. bug fixes and cleanups [Andre, Georges, Christian, Jonas Å., Andre,
 | 
			
		||||
  Simon, Florian, Carlos, Adam, Marco, Thomas, Elias, Pekka, Jonas D.,
 | 
			
		||||
  Laurent; !1169, !1168, !1166, !1170, !1167, !1172, !1175, !1176, !1184,
 | 
			
		||||
  !1126, !1187, !1191, !1195, !1179, !1200, !1193, !1209, !1213, !1208,
 | 
			
		||||
  #1074, !1223]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Marco Trevisan (Treviño), Elias Aebi, Thomas Hindoe Paaboel Andersen,
 | 
			
		||||
  Laurent Bigonville, Jonas Dreßler, Olivier Fourdan, Carlos Garnacho,
 | 
			
		||||
  Adam Jackson, Andre Moreira Magalhaes, Simon McVittie, Florian Müllner,
 | 
			
		||||
  Georges Basile Stavracas Neto, Pekka Paalanen, Christian Rauch, Jonas Troeger,
 | 
			
		||||
  Phillip Wood, Jonas Ådahl
 | 
			
		||||
 | 
			
		||||
Translators:
 | 
			
		||||
  Dušan Kazik [sk], Christian Kirbach [de]
 | 
			
		||||
 | 
			
		||||
3.36.0
 | 
			
		||||
======
 | 
			
		||||
* Fix placement of popup windows in multi-monitor setups [Jonas; !1110]
 | 
			
		||||
* Fix invisible mouse cursor on some hardware [Jonas; !1079]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Jonas Ådahl
 | 
			
		||||
 | 
			
		||||
Translators:
 | 
			
		||||
  Aurimas Černius [lt], Goran Vidović [hr], Anders Jonsson [sv],
 | 
			
		||||
  Guillaume Bernard [fr], Milo Casagrande [it], Daniel Korostil [uk],
 | 
			
		||||
  Andre Klapper [cy], Aman Alam [pa], Nathan Follens [nl]
 | 
			
		||||
 | 
			
		||||
3.35.92
 | 
			
		||||
=======
 | 
			
		||||
* Fix visibility of initially hidden windows [Jonas Å.; !1066]
 | 
			
		||||
* Avoid flicker when (un)redirecting windows [Sebastian; #997]
 | 
			
		||||
* Let BindConstraints update the preferred size [Emmanuele; !1070]
 | 
			
		||||
* Learn about GLES3 [Adam; !882]
 | 
			
		||||
* Ping windows on every window focus [Jonas D.; !891]
 | 
			
		||||
* Remove overhead from hot code paths [Christian;
 | 
			
		||||
  #1056, !1081, !1083, !1071, !1087]
 | 
			
		||||
* Allow remote desktop services to inhibit animations [Jonas Å.; !838]
 | 
			
		||||
* Update screen-cast code to PipeWire 0.3 API [Wim; !1062]
 | 
			
		||||
* Make check-alive timeouts configurable [Jonas Å.; !1080]
 | 
			
		||||
* Make each stage view correspond to a single CRTC [Jonas Å.; !1042]
 | 
			
		||||
* Implement scaled/transformed hardware cursors [Robert; !526]
 | 
			
		||||
* Use DMA buffers for screencasting if possible [Georges; !1086]
 | 
			
		||||
* Make Xwayland startup asynchronous [Carlos; !944]
 | 
			
		||||
* Fix clipping glitches in long text entries [Jonas D.; !1096]
 | 
			
		||||
* Add side channel for starting required X11 services [Carlos; !945]
 | 
			
		||||
* Support synchronized wayland popup moving [Jonas Å.; !705]
 | 
			
		||||
* Fixed crashes [Olivier, Jonas Å.; !1073, !1093]
 | 
			
		||||
* Plugged memory leaks [Sebastian, Jonas Å.; !1089, !1095]
 | 
			
		||||
* Misc. bug fixes and cleanups [Jonas Å, Olivier, Florian, Daniel, Jonas D.,
 | 
			
		||||
  Robert, Sebastian, Christian, Arun, Carlos, worldofpeace; !1061, #1043,
 | 
			
		||||
  !1067, !1068, !1065, !835, !1058, !1069, !1075, #1060, !1077, !423, !1090,
 | 
			
		||||
  !1088, !1094, #1067, !1064, !1099, !957, !1000, !1082]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Emmanuele Bassi, Jonas Dreßler, Olivier Fourdan, Carlos Garnacho,
 | 
			
		||||
  Christian Hergert, Adam Jackson, Sebastian Keller, Robert Mader,
 | 
			
		||||
  Florian Müllner, Georges Basile Stavracas Neto, Arun Raghavan, Wim Taymans,
 | 
			
		||||
  Daniel van Vugt, worldofpeace, Jonas Ådahl
 | 
			
		||||
 | 
			
		||||
Translators:
 | 
			
		||||
  Yi-Jyun Pan [zh_TW], Asier Sarasua Garmendia [eu], Rafael Fontenelle [pt_BR],
 | 
			
		||||
  Emin Tufan Çetin [tr], Daniel Mustieles [es], Balázs Úr [hu],
 | 
			
		||||
  Gwan-gyeong Mun [ko], Marek Černocký [cs], Fran Dieguez [gl],
 | 
			
		||||
  Kukuh Syafaat [id], Alan Mortensen [da], Piotr Drąg [pl], sicklylife [ja],
 | 
			
		||||
  Matej Urbančič [sl]
 | 
			
		||||
 | 
			
		||||
3.35.91
 | 
			
		||||
=======
 | 
			
		||||
* Honor accelerometer orientation on monitor config changes [Hans; !959]
 | 
			
		||||
 
 | 
			
		||||
@@ -88,6 +88,10 @@ static void
 | 
			
		||||
clutter_actor_meta_real_set_actor (ClutterActorMeta *meta,
 | 
			
		||||
                                   ClutterActor     *actor)
 | 
			
		||||
{
 | 
			
		||||
  g_warn_if_fail (!meta->priv->actor ||
 | 
			
		||||
                  !CLUTTER_ACTOR_IN_PAINT (meta->priv->actor));
 | 
			
		||||
  g_warn_if_fail (!actor || !CLUTTER_ACTOR_IN_PAINT (actor));
 | 
			
		||||
 | 
			
		||||
  if (meta->priv->actor == actor)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
@@ -101,6 +105,18 @@ clutter_actor_meta_real_set_actor (ClutterActorMeta *meta,
 | 
			
		||||
                                               meta);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_actor_meta_real_set_enabled (ClutterActorMeta *meta,
 | 
			
		||||
                                     gboolean          is_enabled)
 | 
			
		||||
{
 | 
			
		||||
  g_warn_if_fail (!meta->priv->actor ||
 | 
			
		||||
                  !CLUTTER_ACTOR_IN_PAINT (meta->priv->actor));
 | 
			
		||||
 | 
			
		||||
  meta->priv->is_enabled = is_enabled;
 | 
			
		||||
 | 
			
		||||
  g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_ENABLED]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_actor_meta_set_property (GObject      *gobject,
 | 
			
		||||
                                 guint         prop_id,
 | 
			
		||||
@@ -172,6 +188,7 @@ clutter_actor_meta_class_init (ClutterActorMetaClass *klass)
 | 
			
		||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  klass->set_actor = clutter_actor_meta_real_set_actor;
 | 
			
		||||
  klass->set_enabled = clutter_actor_meta_real_set_enabled;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ClutterActorMeta:actor:
 | 
			
		||||
@@ -298,9 +315,7 @@ clutter_actor_meta_set_enabled (ClutterActorMeta *meta,
 | 
			
		||||
  if (meta->priv->is_enabled == is_enabled)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  meta->priv->is_enabled = is_enabled;
 | 
			
		||||
 | 
			
		||||
  g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_ENABLED]);
 | 
			
		||||
  CLUTTER_ACTOR_META_GET_CLASS (meta)->set_enabled (meta, is_enabled);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
@@ -87,6 +87,9 @@ struct _ClutterActorMetaClass
 | 
			
		||||
  void (* set_actor) (ClutterActorMeta *meta,
 | 
			
		||||
                      ClutterActor     *actor);
 | 
			
		||||
 | 
			
		||||
  void (* set_enabled) (ClutterActorMeta *meta,
 | 
			
		||||
                        gboolean          is_enabled);
 | 
			
		||||
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  void (* _clutter_meta1) (void);
 | 
			
		||||
  void (* _clutter_meta2) (void);
 | 
			
		||||
@@ -94,7 +97,6 @@ struct _ClutterActorMetaClass
 | 
			
		||||
  void (* _clutter_meta4) (void);
 | 
			
		||||
  void (* _clutter_meta5) (void);
 | 
			
		||||
  void (* _clutter_meta6) (void);
 | 
			
		||||
  void (* _clutter_meta7) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
 
 | 
			
		||||
@@ -710,6 +710,7 @@ struct _ClutterActorPrivate
 | 
			
		||||
 | 
			
		||||
  guint8 opacity;
 | 
			
		||||
  gint opacity_override;
 | 
			
		||||
  unsigned int inhibit_culling_counter;
 | 
			
		||||
 | 
			
		||||
  ClutterOffscreenRedirect offscreen_redirect;
 | 
			
		||||
 | 
			
		||||
@@ -2409,6 +2410,7 @@ clutter_actor_should_pick_paint (ClutterActor *self)
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
 | 
			
		||||
 | 
			
		||||
  if (CLUTTER_ACTOR_IS_MAPPED (self) &&
 | 
			
		||||
      clutter_actor_has_allocation (self) &&
 | 
			
		||||
      (_clutter_context_get_pick_mode () == CLUTTER_PICK_ALL ||
 | 
			
		||||
       CLUTTER_ACTOR_IS_REACTIVE (self)))
 | 
			
		||||
    return TRUE;
 | 
			
		||||
@@ -3864,14 +3866,7 @@ clutter_actor_paint_node (ClutterActor        *actor,
 | 
			
		||||
 | 
			
		||||
      fb = clutter_paint_context_get_base_framebuffer (paint_context);
 | 
			
		||||
 | 
			
		||||
      if (clutter_stage_get_use_alpha (CLUTTER_STAGE (actor)))
 | 
			
		||||
        {
 | 
			
		||||
          bg_color.alpha = priv->opacity
 | 
			
		||||
                         * priv->bg_color.alpha
 | 
			
		||||
                         / 255;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        bg_color.alpha = 255;
 | 
			
		||||
      bg_color.alpha = 255;
 | 
			
		||||
 | 
			
		||||
      CLUTTER_NOTE (PAINT, "Stage clear color: (%d, %d, %d, %d)",
 | 
			
		||||
                    bg_color.red,
 | 
			
		||||
@@ -3951,6 +3946,7 @@ clutter_actor_paint (ClutterActor        *self,
 | 
			
		||||
  g_autoptr (ClutterPaintNode) root_node = NULL;
 | 
			
		||||
  ClutterActorPrivate *priv;
 | 
			
		||||
  ClutterActorBox clip;
 | 
			
		||||
  gboolean culling_inhibited;
 | 
			
		||||
  gboolean clip_set = FALSE;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_ACTOR (self));
 | 
			
		||||
@@ -4099,7 +4095,8 @@ clutter_actor_paint (ClutterActor        *self,
 | 
			
		||||
   * paint then the last-paint-volume would likely represent the new
 | 
			
		||||
   * actor position not the old.
 | 
			
		||||
   */
 | 
			
		||||
  if (!in_clone_paint ())
 | 
			
		||||
  culling_inhibited = priv->inhibit_culling_counter > 0;
 | 
			
		||||
  if (!culling_inhibited && !in_clone_paint ())
 | 
			
		||||
    {
 | 
			
		||||
      gboolean success;
 | 
			
		||||
      /* annoyingly gcc warns if uninitialized even though
 | 
			
		||||
@@ -16002,6 +15999,63 @@ clutter_actor_get_opacity_override (ClutterActor *self)
 | 
			
		||||
  return self->priv->opacity_override;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_actor_inhibit_culling:
 | 
			
		||||
 * @actor: a #ClutterActor
 | 
			
		||||
 *
 | 
			
		||||
 * Increases the culling inhibitor counter. Inhibiting culling
 | 
			
		||||
 * forces the actor to be painted even when outside the visible
 | 
			
		||||
 * bounds of the stage view.
 | 
			
		||||
 *
 | 
			
		||||
 * This is usually necessary when an actor is being painted on
 | 
			
		||||
 * another paint context.
 | 
			
		||||
 *
 | 
			
		||||
 * Pair with clutter_actor_uninhibit_culling() when the actor doesn't
 | 
			
		||||
 * need to be painted anymore.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
clutter_actor_inhibit_culling (ClutterActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_ACTOR (actor));
 | 
			
		||||
 | 
			
		||||
  priv = actor->priv;
 | 
			
		||||
 | 
			
		||||
  priv->inhibit_culling_counter++;
 | 
			
		||||
  _clutter_actor_set_enable_paint_unmapped (actor, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_actor_uninhibit_culling:
 | 
			
		||||
 * @actor: a #ClutterActor
 | 
			
		||||
 *
 | 
			
		||||
 * Decreases the culling inhibitor counter. See clutter_actor_inhibit_culling()
 | 
			
		||||
 * for when inhibit culling is necessary.
 | 
			
		||||
 *
 | 
			
		||||
 * Calling this function without a matching call to
 | 
			
		||||
 * clutter_actor_inhibit_culling() is a programming error.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
clutter_actor_uninhibit_culling (ClutterActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_ACTOR (actor));
 | 
			
		||||
 | 
			
		||||
  priv = actor->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->inhibit_culling_counter == 0)
 | 
			
		||||
    {
 | 
			
		||||
      g_critical ("Unpaired call to clutter_actor_uninhibit_culling");
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  priv->inhibit_culling_counter--;
 | 
			
		||||
  if (priv->inhibit_culling_counter == 0)
 | 
			
		||||
    _clutter_actor_set_enable_paint_unmapped (actor, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Allows you to disable applying the actors model view transform during
 | 
			
		||||
 * a paint. Used by ClutterClone. */
 | 
			
		||||
void
 | 
			
		||||
@@ -17715,10 +17769,42 @@ _clutter_actor_compute_resource_scale (ClutterActor *self,
 | 
			
		||||
                                                   resource_scale))
 | 
			
		||||
    {
 | 
			
		||||
      if (priv->parent)
 | 
			
		||||
        return _clutter_actor_compute_resource_scale (priv->parent,
 | 
			
		||||
                                                      resource_scale);
 | 
			
		||||
        {
 | 
			
		||||
          gboolean in_clone_paint;
 | 
			
		||||
          gboolean was_parent_in_clone_paint;
 | 
			
		||||
          gboolean was_parent_unmapped;
 | 
			
		||||
          gboolean was_parent_paint_unmapped;
 | 
			
		||||
          gboolean ret;
 | 
			
		||||
 | 
			
		||||
          in_clone_paint = clutter_actor_is_in_clone_paint (self);
 | 
			
		||||
          was_parent_unmapped = !clutter_actor_is_mapped (priv->parent);
 | 
			
		||||
          was_parent_in_clone_paint =
 | 
			
		||||
            clutter_actor_is_in_clone_paint (priv->parent);
 | 
			
		||||
          was_parent_paint_unmapped = priv->parent->priv->enable_paint_unmapped;
 | 
			
		||||
 | 
			
		||||
          if (in_clone_paint && was_parent_unmapped)
 | 
			
		||||
            {
 | 
			
		||||
              _clutter_actor_set_in_clone_paint (priv->parent, TRUE);
 | 
			
		||||
              _clutter_actor_set_enable_paint_unmapped (priv->parent, TRUE);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          ret = _clutter_actor_compute_resource_scale (priv->parent,
 | 
			
		||||
                                                       resource_scale);
 | 
			
		||||
 | 
			
		||||
          if (in_clone_paint && was_parent_unmapped)
 | 
			
		||||
            {
 | 
			
		||||
              _clutter_actor_set_in_clone_paint (priv->parent,
 | 
			
		||||
                                                 was_parent_in_clone_paint);
 | 
			
		||||
              _clutter_actor_set_enable_paint_unmapped (priv->parent,
 | 
			
		||||
                                                        was_parent_paint_unmapped);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          return ret;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        return FALSE;
 | 
			
		||||
        {
 | 
			
		||||
          return FALSE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
@@ -19874,6 +19960,23 @@ clutter_actor_get_transition (ClutterActor *self,
 | 
			
		||||
  return clos->transition;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_actor_has_transitions: (skip)
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
clutter_actor_has_transitions (ClutterActor *self)
 | 
			
		||||
{
 | 
			
		||||
  const ClutterAnimationInfo *info;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
 | 
			
		||||
 | 
			
		||||
  info = _clutter_actor_get_animation_info_or_defaults (self);
 | 
			
		||||
  if (info->transitions == NULL)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return g_hash_table_size (info->transitions) > 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_actor_save_easing_state:
 | 
			
		||||
 * @self: a #ClutterActor
 | 
			
		||||
 
 | 
			
		||||
@@ -884,6 +884,11 @@ void                            clutter_actor_set_opacity_override
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
gint                            clutter_actor_get_opacity_override              (ClutterActor               *self);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void                            clutter_actor_inhibit_culling                   (ClutterActor               *actor);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void                            clutter_actor_uninhibit_culling                 (ClutterActor               *actor);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ClutterActorCreateChildFunc:
 | 
			
		||||
 * @item: (type GObject): the item in the model
 | 
			
		||||
 
 | 
			
		||||
@@ -50,8 +50,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterConstraint, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterContainer, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDeformEffect, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDesaturateEffect, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDragAction, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDropAction, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterEffect, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFixedLayout, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFlowLayout, g_object_unref)
 | 
			
		||||
 
 | 
			
		||||
@@ -238,6 +238,7 @@ click_action_query_long_press (ClutterClickAction *action)
 | 
			
		||||
 | 
			
		||||
  if (result)
 | 
			
		||||
    {
 | 
			
		||||
      g_clear_handle_id (&priv->long_press_id, g_source_remove);
 | 
			
		||||
      priv->long_press_id =
 | 
			
		||||
        clutter_threads_add_timeout (timeout,
 | 
			
		||||
                                     click_action_emit_long_press,
 | 
			
		||||
@@ -467,6 +468,20 @@ clutter_click_action_set_actor (ClutterActorMeta *meta,
 | 
			
		||||
  CLUTTER_ACTOR_META_CLASS (clutter_click_action_parent_class)->set_actor (meta, actor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_click_action_set_enabled (ClutterActorMeta *meta,
 | 
			
		||||
                                  gboolean          is_enabled)
 | 
			
		||||
{
 | 
			
		||||
  ClutterClickAction *click_action = CLUTTER_CLICK_ACTION (meta);
 | 
			
		||||
  ClutterActorMetaClass *parent_class =
 | 
			
		||||
    CLUTTER_ACTOR_META_CLASS (clutter_click_action_parent_class);
 | 
			
		||||
 | 
			
		||||
  if (!is_enabled)
 | 
			
		||||
    clutter_click_action_release (click_action);
 | 
			
		||||
 | 
			
		||||
  parent_class->set_enabled (meta, is_enabled);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_click_action_set_property (GObject      *gobject,
 | 
			
		||||
                                   guint         prop_id,
 | 
			
		||||
@@ -546,6 +561,7 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
 | 
			
		||||
  ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  meta_class->set_actor = clutter_click_action_set_actor;
 | 
			
		||||
  meta_class->set_enabled = clutter_click_action_set_enabled;
 | 
			
		||||
 | 
			
		||||
  gobject_class->dispose = clutter_click_action_dispose;
 | 
			
		||||
  gobject_class->set_property = clutter_click_action_set_property;
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,13 @@
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
@CLUTTER_CONFIG_DEFINES@
 | 
			
		||||
#mesondefine CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT
 | 
			
		||||
#mesondefine CLUTTER_WINDOWING_X11
 | 
			
		||||
#mesondefine CLUTTER_INPUT_X11
 | 
			
		||||
#mesondefine CLUTTER_WINDOWING_GLX
 | 
			
		||||
#mesondefine CLUTTER_WINDOWING_EGL
 | 
			
		||||
#mesondefine CLUTTER_INPUT_EVDEV
 | 
			
		||||
#mesondefine CLUTTER_INPUT_NULL
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -160,28 +160,26 @@ constraint_update_preferred_size (ClutterConstraint  *constraint,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_constraint_notify (GObject    *gobject,
 | 
			
		||||
                           GParamSpec *pspec)
 | 
			
		||||
clutter_constraint_set_enabled (ClutterActorMeta *meta,
 | 
			
		||||
                                gboolean          is_enabled)
 | 
			
		||||
{
 | 
			
		||||
  if (strcmp (pspec->name, "enabled") == 0)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterActorMeta *meta = CLUTTER_ACTOR_META (gobject);
 | 
			
		||||
      ClutterActor *actor = clutter_actor_meta_get_actor (meta);
 | 
			
		||||
  ClutterActorMetaClass *parent_class =
 | 
			
		||||
    CLUTTER_ACTOR_META_CLASS (clutter_constraint_parent_class);
 | 
			
		||||
  ClutterActor *actor;
 | 
			
		||||
 | 
			
		||||
      if (actor != NULL)
 | 
			
		||||
        clutter_actor_queue_relayout (actor);
 | 
			
		||||
    }
 | 
			
		||||
  actor = clutter_actor_meta_get_actor (meta);
 | 
			
		||||
  if (actor)
 | 
			
		||||
    clutter_actor_queue_relayout (actor);
 | 
			
		||||
 | 
			
		||||
  if (G_OBJECT_CLASS (clutter_constraint_parent_class)->notify != NULL)
 | 
			
		||||
    G_OBJECT_CLASS (clutter_constraint_parent_class)->notify (gobject, pspec);
 | 
			
		||||
  parent_class->set_enabled (meta, is_enabled);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_constraint_class_init (ClutterConstraintClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  ClutterActorMetaClass *actor_meta_class = CLUTTER_ACTOR_META_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  gobject_class->notify = clutter_constraint_notify;
 | 
			
		||||
  actor_meta_class->set_enabled = clutter_constraint_set_enabled;
 | 
			
		||||
 | 
			
		||||
  klass->update_allocation = constraint_update_allocation;
 | 
			
		||||
  klass->update_preferred_size = constraint_update_preferred_size;
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,152 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Clutter.
 | 
			
		||||
 *
 | 
			
		||||
 * An OpenGL based 'interactive canvas' library.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2010  Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author:
 | 
			
		||||
 *   Emmanuele Bassi <ebassi@linux.intel.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __CLUTTER_DRAG_ACTION_H__
 | 
			
		||||
#define __CLUTTER_DRAG_ACTION_H__
 | 
			
		||||
 | 
			
		||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
 | 
			
		||||
#error "Only <clutter/clutter.h> can be included directly."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter-action.h>
 | 
			
		||||
#include <clutter/clutter-event.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define CLUTTER_TYPE_DRAG_ACTION                (clutter_drag_action_get_type ())
 | 
			
		||||
#define CLUTTER_DRAG_ACTION(obj)                (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_DRAG_ACTION, ClutterDragAction))
 | 
			
		||||
#define CLUTTER_IS_DRAG_ACTION(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_DRAG_ACTION))
 | 
			
		||||
#define CLUTTER_DRAG_ACTION_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_DRAG_ACTION, ClutterDragActionClass))
 | 
			
		||||
#define CLUTTER_IS_DRAG_ACTION_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_DRAG_ACTION))
 | 
			
		||||
#define CLUTTER_DRAG_ACTION_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_DRAG_ACTION, ClutterDragActionClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _ClutterDragAction               ClutterDragAction;
 | 
			
		||||
typedef struct _ClutterDragActionPrivate        ClutterDragActionPrivate;
 | 
			
		||||
typedef struct _ClutterDragActionClass          ClutterDragActionClass;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ClutterDragAction:
 | 
			
		||||
 *
 | 
			
		||||
 * The #ClutterDragAction structure contains only
 | 
			
		||||
 * private data and should be accessed using the provided API
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
struct _ClutterDragAction
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  ClutterAction parent_instance;
 | 
			
		||||
 | 
			
		||||
  ClutterDragActionPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ClutterDragActionClass:
 | 
			
		||||
 * @drag_begin: class handler of the #ClutterDragAction::drag-begin signal
 | 
			
		||||
 * @drag_motion: class handler of the #ClutterDragAction::drag-motion signal
 | 
			
		||||
 * @drag_end: class handler of the #ClutterDragAction::drag-end signal
 | 
			
		||||
 * @drag_progress: class handler of the #ClutterDragAction::drag-progress signal
 | 
			
		||||
 *
 | 
			
		||||
 * The #ClutterDragActionClass structure contains
 | 
			
		||||
 * only private data
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
struct _ClutterDragActionClass
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  ClutterActionClass parent_class;
 | 
			
		||||
 | 
			
		||||
  /*< public >*/
 | 
			
		||||
  void          (* drag_begin)          (ClutterDragAction   *action,
 | 
			
		||||
                                         ClutterActor        *actor,
 | 
			
		||||
                                         gfloat               event_x,
 | 
			
		||||
                                         gfloat               event_y,
 | 
			
		||||
                                         ClutterModifierType  modifiers);
 | 
			
		||||
  void          (* drag_motion)         (ClutterDragAction   *action,
 | 
			
		||||
                                         ClutterActor        *actor,
 | 
			
		||||
                                         gfloat               delta_x,
 | 
			
		||||
                                         gfloat               delta_y);
 | 
			
		||||
  void          (* drag_end)            (ClutterDragAction   *action,
 | 
			
		||||
                                         ClutterActor        *actor,
 | 
			
		||||
                                         gfloat               event_x,
 | 
			
		||||
                                         gfloat               event_y,
 | 
			
		||||
                                         ClutterModifierType  modifiers);
 | 
			
		||||
  gboolean      (* drag_progress)       (ClutterDragAction   *action,
 | 
			
		||||
                                         ClutterActor        *actor,
 | 
			
		||||
                                         gfloat               delta_x,
 | 
			
		||||
                                         gfloat               delta_y);
 | 
			
		||||
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  void (* _clutter_drag_action1) (void);
 | 
			
		||||
  void (* _clutter_drag_action2) (void);
 | 
			
		||||
  void (* _clutter_drag_action3) (void);
 | 
			
		||||
  void (* _clutter_drag_action4) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
GType clutter_drag_action_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
ClutterAction * clutter_drag_action_new                   (void);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void            clutter_drag_action_set_drag_threshold (ClutterDragAction *action,
 | 
			
		||||
                                                        gint               x_threshold,
 | 
			
		||||
                                                        gint               y_threshold);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void            clutter_drag_action_get_drag_threshold (ClutterDragAction *action,
 | 
			
		||||
                                                        guint             *x_threshold,
 | 
			
		||||
                                                        guint             *y_threshold);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void            clutter_drag_action_set_drag_handle    (ClutterDragAction *action,
 | 
			
		||||
                                                        ClutterActor      *handle);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
ClutterActor *  clutter_drag_action_get_drag_handle    (ClutterDragAction *action);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void            clutter_drag_action_set_drag_axis      (ClutterDragAction *action,
 | 
			
		||||
                                                        ClutterDragAxis    axis);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
ClutterDragAxis clutter_drag_action_get_drag_axis      (ClutterDragAction *action);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void            clutter_drag_action_get_press_coords   (ClutterDragAction *action,
 | 
			
		||||
                                                        gfloat            *press_x,
 | 
			
		||||
                                                        gfloat            *press_y);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void            clutter_drag_action_get_motion_coords  (ClutterDragAction *action,
 | 
			
		||||
                                                        gfloat            *motion_x,
 | 
			
		||||
                                                        gfloat            *motion_y);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
gboolean        clutter_drag_action_get_drag_area      (ClutterDragAction *action,
 | 
			
		||||
                                                        graphene_rect_t   *drag_area);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void            clutter_drag_action_set_drag_area      (ClutterDragAction     *action,
 | 
			
		||||
                                                        const graphene_rect_t *drag_area);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __CLUTTER_DRAG_ACTION_H__ */
 | 
			
		||||
@@ -1,527 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Clutter.
 | 
			
		||||
 *
 | 
			
		||||
 * An OpenGL based 'interactive canvas' library.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright © 2011  Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author:
 | 
			
		||||
 *   Emmanuele Bassi <ebassi@linux.intel.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:clutter-drop-action
 | 
			
		||||
 * @Title: ClutterDropAction
 | 
			
		||||
 * @short_description: An action for drop targets
 | 
			
		||||
 *
 | 
			
		||||
 * #ClutterDropAction is a #ClutterAction that allows a #ClutterActor
 | 
			
		||||
 * implementation to control what happens when an actor dragged using
 | 
			
		||||
 * a #ClutterDragAction crosses the target area or when a dragged actor
 | 
			
		||||
 * is released (or "dropped") on the target area.
 | 
			
		||||
 *
 | 
			
		||||
 * A trivial use of #ClutterDropAction consists in connecting to the
 | 
			
		||||
 * #ClutterDropAction::drop signal and handling the drop from there,
 | 
			
		||||
 * for instance:
 | 
			
		||||
 *
 | 
			
		||||
 * |[<!-- language="C" -->
 | 
			
		||||
 *   ClutterAction *action = clutter_drop_action ();
 | 
			
		||||
 *
 | 
			
		||||
 *   g_signal_connect (action, "drop", G_CALLBACK (on_drop), NULL);
 | 
			
		||||
 *   clutter_actor_add_action (an_actor, action);
 | 
			
		||||
 * ]|
 | 
			
		||||
 *
 | 
			
		||||
 * The #ClutterDropAction::can-drop can be used to control whether the
 | 
			
		||||
 * #ClutterDropAction::drop signal is going to be emitted; returning %FALSE
 | 
			
		||||
 * from a handler connected to the #ClutterDropAction::can-drop signal will
 | 
			
		||||
 * cause the #ClutterDropAction::drop signal to be skipped when the input
 | 
			
		||||
 * device button is released.
 | 
			
		||||
 *
 | 
			
		||||
 * It's important to note that #ClutterDropAction will only work with
 | 
			
		||||
 * actors dragged using #ClutterDragAction.
 | 
			
		||||
 *
 | 
			
		||||
 * See [drop-action.c](https://git.gnome.org/browse/clutter/tree/examples/drop-action.c?h=clutter-1.18)
 | 
			
		||||
 * for an example of how to use #ClutterDropAction.
 | 
			
		||||
 *
 | 
			
		||||
 * #ClutterDropAction is available since Clutter 1.8
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "clutter-build-config.h"
 | 
			
		||||
 | 
			
		||||
#include "clutter-drop-action.h"
 | 
			
		||||
 | 
			
		||||
#include "clutter-actor-meta-private.h"
 | 
			
		||||
#include "clutter-actor-private.h"
 | 
			
		||||
#include "clutter-drag-action.h"
 | 
			
		||||
#include "clutter-main.h"
 | 
			
		||||
#include "clutter-marshal.h"
 | 
			
		||||
#include "clutter-stage-private.h"
 | 
			
		||||
 | 
			
		||||
struct _ClutterDropActionPrivate
 | 
			
		||||
{
 | 
			
		||||
  ClutterActor *actor;
 | 
			
		||||
  ClutterActor *stage;
 | 
			
		||||
 | 
			
		||||
  gulong mapped_id;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _DropTarget {
 | 
			
		||||
  ClutterActor *stage;
 | 
			
		||||
 | 
			
		||||
  gulong capture_id;
 | 
			
		||||
 | 
			
		||||
  GHashTable *actions;
 | 
			
		||||
 | 
			
		||||
  ClutterDropAction *last_action;
 | 
			
		||||
} DropTarget;
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  CAN_DROP,
 | 
			
		||||
  OVER_IN,
 | 
			
		||||
  OVER_OUT,
 | 
			
		||||
  DROP,
 | 
			
		||||
  DROP_CANCEL,
 | 
			
		||||
 | 
			
		||||
  LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint drop_signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterDropAction, clutter_drop_action, CLUTTER_TYPE_ACTION)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
drop_target_free (gpointer _data)
 | 
			
		||||
{
 | 
			
		||||
  DropTarget *data = _data;
 | 
			
		||||
 | 
			
		||||
  g_clear_signal_handler (&data->capture_id, data->stage);
 | 
			
		||||
  g_hash_table_destroy (data->actions);
 | 
			
		||||
  g_free (data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
on_stage_capture (ClutterStage *stage,
 | 
			
		||||
                  ClutterEvent *event,
 | 
			
		||||
                  gpointer      user_data)
 | 
			
		||||
{
 | 
			
		||||
  DropTarget *data = user_data;
 | 
			
		||||
  gfloat event_x, event_y;
 | 
			
		||||
  ClutterActor *actor, *drag_actor;
 | 
			
		||||
  ClutterDropAction *drop_action;
 | 
			
		||||
  ClutterInputDevice *device;
 | 
			
		||||
  gboolean was_reactive;
 | 
			
		||||
 | 
			
		||||
  switch (clutter_event_type (event))
 | 
			
		||||
    {
 | 
			
		||||
    case CLUTTER_MOTION:
 | 
			
		||||
    case CLUTTER_BUTTON_RELEASE:
 | 
			
		||||
      if (clutter_event_type (event) == CLUTTER_MOTION &&
 | 
			
		||||
          !(clutter_event_get_state (event) & CLUTTER_BUTTON1_MASK))
 | 
			
		||||
        return CLUTTER_EVENT_PROPAGATE;
 | 
			
		||||
 | 
			
		||||
      if (clutter_event_type (event) == CLUTTER_BUTTON_RELEASE &&
 | 
			
		||||
          clutter_event_get_button (event) != CLUTTER_BUTTON_PRIMARY)
 | 
			
		||||
        return CLUTTER_EVENT_PROPAGATE;
 | 
			
		||||
 | 
			
		||||
      device = clutter_event_get_device (event);
 | 
			
		||||
      drag_actor = _clutter_stage_get_pointer_drag_actor (stage, device);
 | 
			
		||||
      if (drag_actor == NULL)
 | 
			
		||||
        return CLUTTER_EVENT_PROPAGATE;
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case CLUTTER_TOUCH_UPDATE:
 | 
			
		||||
    case CLUTTER_TOUCH_END:
 | 
			
		||||
      drag_actor = _clutter_stage_get_touch_drag_actor (stage,
 | 
			
		||||
                                                        clutter_event_get_event_sequence (event));
 | 
			
		||||
      if (drag_actor == NULL)
 | 
			
		||||
        return CLUTTER_EVENT_PROPAGATE;
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      return CLUTTER_EVENT_PROPAGATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  clutter_event_get_coords (event, &event_x, &event_y);
 | 
			
		||||
 | 
			
		||||
  /* get the actor under the cursor, excluding the dragged actor; we
 | 
			
		||||
   * use reactivity because it won't cause any scene invalidation
 | 
			
		||||
   */
 | 
			
		||||
  was_reactive = clutter_actor_get_reactive (drag_actor);
 | 
			
		||||
  clutter_actor_set_reactive (drag_actor, FALSE);
 | 
			
		||||
 | 
			
		||||
  actor = clutter_stage_get_actor_at_pos (stage, CLUTTER_PICK_REACTIVE,
 | 
			
		||||
                                          event_x,
 | 
			
		||||
                                          event_y);
 | 
			
		||||
  if (actor == NULL || actor == CLUTTER_ACTOR (stage))
 | 
			
		||||
    {
 | 
			
		||||
      if (data->last_action != NULL)
 | 
			
		||||
        {
 | 
			
		||||
          ClutterActorMeta *meta = CLUTTER_ACTOR_META (data->last_action);
 | 
			
		||||
 | 
			
		||||
          g_signal_emit (data->last_action, drop_signals[OVER_OUT], 0,
 | 
			
		||||
                         clutter_actor_meta_get_actor (meta));
 | 
			
		||||
 | 
			
		||||
          data->last_action = NULL;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  drop_action = g_hash_table_lookup (data->actions, actor);
 | 
			
		||||
 | 
			
		||||
  if (drop_action == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      if (data->last_action != NULL)
 | 
			
		||||
        {
 | 
			
		||||
          ClutterActorMeta *meta = CLUTTER_ACTOR_META (data->last_action);
 | 
			
		||||
 | 
			
		||||
          g_signal_emit (data->last_action, drop_signals[OVER_OUT], 0,
 | 
			
		||||
                         clutter_actor_meta_get_actor (meta));
 | 
			
		||||
 | 
			
		||||
          data->last_action = NULL;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      goto out;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      if (data->last_action != drop_action)
 | 
			
		||||
        {
 | 
			
		||||
          ClutterActorMeta *meta;
 | 
			
		||||
 | 
			
		||||
          if (data->last_action != NULL)
 | 
			
		||||
            {
 | 
			
		||||
              meta = CLUTTER_ACTOR_META (data->last_action);
 | 
			
		||||
 | 
			
		||||
              g_signal_emit (data->last_action, drop_signals[OVER_OUT], 0,
 | 
			
		||||
                             clutter_actor_meta_get_actor (meta));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          meta = CLUTTER_ACTOR_META (drop_action);
 | 
			
		||||
 | 
			
		||||
          g_signal_emit (drop_action, drop_signals[OVER_IN], 0,
 | 
			
		||||
                         clutter_actor_meta_get_actor (meta));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      data->last_action = drop_action;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
  if (clutter_event_type (event) == CLUTTER_BUTTON_RELEASE ||
 | 
			
		||||
      clutter_event_type (event) == CLUTTER_TOUCH_END)
 | 
			
		||||
    {
 | 
			
		||||
      if (data->last_action != NULL)
 | 
			
		||||
        {
 | 
			
		||||
          ClutterActorMeta *meta = CLUTTER_ACTOR_META (data->last_action);
 | 
			
		||||
          gboolean can_drop = FALSE;
 | 
			
		||||
 | 
			
		||||
          g_signal_emit (data->last_action, drop_signals[CAN_DROP], 0,
 | 
			
		||||
                         clutter_actor_meta_get_actor (meta),
 | 
			
		||||
                         event_x, event_y,
 | 
			
		||||
                         &can_drop);
 | 
			
		||||
 | 
			
		||||
          if (can_drop)
 | 
			
		||||
            {
 | 
			
		||||
              g_signal_emit (data->last_action, drop_signals[DROP], 0,
 | 
			
		||||
                             clutter_actor_meta_get_actor (meta),
 | 
			
		||||
                             event_x, event_y);
 | 
			
		||||
            }
 | 
			
		||||
	  else
 | 
			
		||||
            {
 | 
			
		||||
              g_signal_emit (data->last_action, drop_signals[DROP_CANCEL], 0,
 | 
			
		||||
                             clutter_actor_meta_get_actor (meta),
 | 
			
		||||
                             event_x, event_y);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      data->last_action = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (drag_actor != NULL)
 | 
			
		||||
    clutter_actor_set_reactive (drag_actor, was_reactive);
 | 
			
		||||
 | 
			
		||||
  return CLUTTER_EVENT_PROPAGATE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
drop_action_register (ClutterDropAction *self)
 | 
			
		||||
{
 | 
			
		||||
  ClutterDropActionPrivate *priv = self->priv;
 | 
			
		||||
  DropTarget *data;
 | 
			
		||||
 | 
			
		||||
  g_assert (priv->stage != NULL);
 | 
			
		||||
 | 
			
		||||
  data = g_object_get_data (G_OBJECT (priv->stage), "__clutter_drop_targets");
 | 
			
		||||
  if (data == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      data = g_new0 (DropTarget, 1);
 | 
			
		||||
 | 
			
		||||
      data->stage = priv->stage;
 | 
			
		||||
      data->actions = g_hash_table_new (NULL, NULL);
 | 
			
		||||
      data->capture_id = g_signal_connect (priv->stage, "captured-event",
 | 
			
		||||
                                           G_CALLBACK (on_stage_capture),
 | 
			
		||||
                                           data);
 | 
			
		||||
      g_object_set_data_full (G_OBJECT (priv->stage), "__clutter_drop_targets",
 | 
			
		||||
                              data,
 | 
			
		||||
                              drop_target_free);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_hash_table_replace (data->actions, priv->actor, self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
drop_action_unregister (ClutterDropAction *self)
 | 
			
		||||
{
 | 
			
		||||
  ClutterDropActionPrivate *priv = self->priv;
 | 
			
		||||
  DropTarget *data = NULL;
 | 
			
		||||
 | 
			
		||||
  if (priv->stage != NULL)
 | 
			
		||||
    data = g_object_get_data (G_OBJECT (priv->stage), "__clutter_drop_targets");
 | 
			
		||||
 | 
			
		||||
  if (data == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  g_hash_table_remove (data->actions, priv->actor);
 | 
			
		||||
  if (g_hash_table_size (data->actions) == 0)
 | 
			
		||||
    g_object_set_data (G_OBJECT (data->stage), "__clutter_drop_targets", NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_actor_mapped (ClutterActor      *actor,
 | 
			
		||||
                 GParamSpec        *pspec,
 | 
			
		||||
                 ClutterDropAction *self)
 | 
			
		||||
{
 | 
			
		||||
  if (clutter_actor_is_mapped (actor))
 | 
			
		||||
    {
 | 
			
		||||
      if (self->priv->stage == NULL)
 | 
			
		||||
        self->priv->stage = clutter_actor_get_stage (actor);
 | 
			
		||||
 | 
			
		||||
      drop_action_register (self);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    drop_action_unregister (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_drop_action_set_actor (ClutterActorMeta *meta,
 | 
			
		||||
                               ClutterActor     *actor)
 | 
			
		||||
{
 | 
			
		||||
  ClutterDropActionPrivate *priv = CLUTTER_DROP_ACTION (meta)->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->actor != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      drop_action_unregister (CLUTTER_DROP_ACTION (meta));
 | 
			
		||||
 | 
			
		||||
      g_clear_signal_handler (&priv->mapped_id, priv->actor);
 | 
			
		||||
 | 
			
		||||
      priv->stage = NULL;
 | 
			
		||||
      priv->actor = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  priv->actor = actor;
 | 
			
		||||
 | 
			
		||||
  if (priv->actor != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      priv->stage = clutter_actor_get_stage (actor);
 | 
			
		||||
      priv->mapped_id = g_signal_connect (actor, "notify::mapped",
 | 
			
		||||
                                          G_CALLBACK (on_actor_mapped),
 | 
			
		||||
                                          meta);
 | 
			
		||||
 | 
			
		||||
      if (priv->stage != NULL)
 | 
			
		||||
        drop_action_register (CLUTTER_DROP_ACTION (meta));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  CLUTTER_ACTOR_META_CLASS (clutter_drop_action_parent_class)->set_actor (meta, actor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
signal_accumulator (GSignalInvocationHint *ihint,
 | 
			
		||||
                    GValue                *return_accu,
 | 
			
		||||
                    const GValue          *handler_return,
 | 
			
		||||
                    gpointer               user_data)
 | 
			
		||||
{
 | 
			
		||||
  gboolean continue_emission;
 | 
			
		||||
 | 
			
		||||
  continue_emission = g_value_get_boolean (handler_return);
 | 
			
		||||
  g_value_set_boolean (return_accu, continue_emission);
 | 
			
		||||
 | 
			
		||||
  return continue_emission;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
clutter_drop_action_real_can_drop (ClutterDropAction *action,
 | 
			
		||||
                                   ClutterActor      *actor,
 | 
			
		||||
                                   gfloat             event_x,
 | 
			
		||||
                                   gfloat             event_y)
 | 
			
		||||
{
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_drop_action_class_init (ClutterDropActionClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  meta_class->set_actor = clutter_drop_action_set_actor;
 | 
			
		||||
 | 
			
		||||
  klass->can_drop = clutter_drop_action_real_can_drop;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ClutterDropAction::can-drop:
 | 
			
		||||
   * @action: the #ClutterDropAction that emitted the signal
 | 
			
		||||
   * @actor: the #ClutterActor attached to the @action
 | 
			
		||||
   * @event_x: the X coordinate (in stage space) of the drop event
 | 
			
		||||
   * @event_y: the Y coordinate (in stage space) of the drop event
 | 
			
		||||
   *
 | 
			
		||||
   * The ::can-drop signal is emitted when the dragged actor is dropped
 | 
			
		||||
   * on @actor. The return value of the ::can-drop signal will determine
 | 
			
		||||
   * whether or not the #ClutterDropAction::drop signal is going to be
 | 
			
		||||
   * emitted on @action.
 | 
			
		||||
   *
 | 
			
		||||
   * The default implementation of #ClutterDropAction returns %TRUE for
 | 
			
		||||
   * this signal.
 | 
			
		||||
   *
 | 
			
		||||
   * Return value: %TRUE if the drop is accepted, and %FALSE otherwise
 | 
			
		||||
   *
 | 
			
		||||
   * Since: 1.8
 | 
			
		||||
   */
 | 
			
		||||
  drop_signals[CAN_DROP] =
 | 
			
		||||
    g_signal_new (I_("can-drop"),
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  G_STRUCT_OFFSET (ClutterDropActionClass, can_drop),
 | 
			
		||||
                  signal_accumulator, NULL,
 | 
			
		||||
                  _clutter_marshal_BOOLEAN__OBJECT_FLOAT_FLOAT,
 | 
			
		||||
                  G_TYPE_BOOLEAN, 3,
 | 
			
		||||
                  CLUTTER_TYPE_ACTOR,
 | 
			
		||||
                  G_TYPE_FLOAT,
 | 
			
		||||
                  G_TYPE_FLOAT);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ClutterDropAction::over-in:
 | 
			
		||||
   * @action: the #ClutterDropAction that emitted the signal
 | 
			
		||||
   * @actor: the #ClutterActor attached to the @action
 | 
			
		||||
   *
 | 
			
		||||
   * The ::over-in signal is emitted when the dragged actor crosses
 | 
			
		||||
   * into @actor.
 | 
			
		||||
   *
 | 
			
		||||
   * Since: 1.8
 | 
			
		||||
   */
 | 
			
		||||
  drop_signals[OVER_IN] =
 | 
			
		||||
    g_signal_new (I_("over-in"),
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  G_STRUCT_OFFSET (ClutterDropActionClass, over_in),
 | 
			
		||||
                  NULL, NULL, NULL,
 | 
			
		||||
                  G_TYPE_NONE, 1,
 | 
			
		||||
                  CLUTTER_TYPE_ACTOR);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ClutterDropAction::over-out:
 | 
			
		||||
   * @action: the #ClutterDropAction that emitted the signal
 | 
			
		||||
   * @actor: the #ClutterActor attached to the @action
 | 
			
		||||
   *
 | 
			
		||||
   * The ::over-out signal is emitted when the dragged actor crosses
 | 
			
		||||
   * outside @actor.
 | 
			
		||||
   *
 | 
			
		||||
   * Since: 1.8
 | 
			
		||||
   */
 | 
			
		||||
  drop_signals[OVER_OUT] =
 | 
			
		||||
    g_signal_new (I_("over-out"),
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  G_STRUCT_OFFSET (ClutterDropActionClass, over_out),
 | 
			
		||||
                  NULL, NULL, NULL,
 | 
			
		||||
                  G_TYPE_NONE, 1,
 | 
			
		||||
                  CLUTTER_TYPE_ACTOR);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ClutterDropAction::drop:
 | 
			
		||||
   * @action: the #ClutterDropAction that emitted the signal
 | 
			
		||||
   * @actor: the #ClutterActor attached to the @action
 | 
			
		||||
   * @event_x: the X coordinate (in stage space) of the drop event
 | 
			
		||||
   * @event_y: the Y coordinate (in stage space) of the drop event
 | 
			
		||||
   *
 | 
			
		||||
   * The ::drop signal is emitted when the dragged actor is dropped
 | 
			
		||||
   * on @actor. This signal is only emitted if at least an handler of
 | 
			
		||||
   * #ClutterDropAction::can-drop returns %TRUE.
 | 
			
		||||
   *
 | 
			
		||||
   * Since: 1.8
 | 
			
		||||
   */
 | 
			
		||||
  drop_signals[DROP] =
 | 
			
		||||
    g_signal_new (I_("drop"),
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  G_STRUCT_OFFSET (ClutterDropActionClass, drop),
 | 
			
		||||
                  NULL, NULL,
 | 
			
		||||
                  _clutter_marshal_VOID__OBJECT_FLOAT_FLOAT,
 | 
			
		||||
                  G_TYPE_NONE, 3,
 | 
			
		||||
                  CLUTTER_TYPE_ACTOR,
 | 
			
		||||
                  G_TYPE_FLOAT,
 | 
			
		||||
                  G_TYPE_FLOAT);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ClutterDropAction::drop-cancel:
 | 
			
		||||
   * @action: the #ClutterDropAction that emitted the signal
 | 
			
		||||
   * @actor: the #ClutterActor attached to the @action
 | 
			
		||||
   * @event_x: the X coordinate (in stage space) of the drop event
 | 
			
		||||
   * @event_y: the Y coordinate (in stage space) of the drop event
 | 
			
		||||
   *
 | 
			
		||||
   * The ::drop-cancel signal is emitted when the drop is refused
 | 
			
		||||
   * by an emission of the #ClutterDropAction::can-drop signal.
 | 
			
		||||
   *
 | 
			
		||||
   * After the ::drop-cancel signal is fired the active drag is
 | 
			
		||||
   * terminated.
 | 
			
		||||
   *
 | 
			
		||||
   * Since: 1.12
 | 
			
		||||
   */
 | 
			
		||||
  drop_signals[DROP_CANCEL] =
 | 
			
		||||
    g_signal_new (I_("drop-cancel"),
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  G_STRUCT_OFFSET (ClutterDropActionClass, drop),
 | 
			
		||||
                  NULL, NULL,
 | 
			
		||||
                  _clutter_marshal_VOID__OBJECT_FLOAT_FLOAT,
 | 
			
		||||
                  G_TYPE_NONE, 3,
 | 
			
		||||
                  CLUTTER_TYPE_ACTOR,
 | 
			
		||||
                  G_TYPE_FLOAT,
 | 
			
		||||
                  G_TYPE_FLOAT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_drop_action_init (ClutterDropAction *self)
 | 
			
		||||
{
 | 
			
		||||
  self->priv = clutter_drop_action_get_instance_private (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_drop_action_new:
 | 
			
		||||
 *
 | 
			
		||||
 * Creates a new #ClutterDropAction.
 | 
			
		||||
 *
 | 
			
		||||
 * Use clutter_actor_add_action() to add the action to a #ClutterActor.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the newly created #ClutterDropAction
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.8
 | 
			
		||||
 */
 | 
			
		||||
ClutterAction *
 | 
			
		||||
clutter_drop_action_new (void)
 | 
			
		||||
{
 | 
			
		||||
  return g_object_new (CLUTTER_TYPE_DROP_ACTION, NULL);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,115 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Clutter.
 | 
			
		||||
 *
 | 
			
		||||
 * An OpenGL based 'interactive canvas' library.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright © 2011  Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author:
 | 
			
		||||
 *   Emmanuele Bassi <ebassi@linux.intel.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __CLUTTER_DROP_ACTION_H__
 | 
			
		||||
#define __CLUTTER_DROP_ACTION_H__
 | 
			
		||||
 | 
			
		||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
 | 
			
		||||
#error "Only <clutter/clutter.h> can be directly included."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter-action.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define CLUTTER_TYPE_DROP_ACTION                (clutter_drop_action_get_type ())
 | 
			
		||||
#define CLUTTER_DROP_ACTION(obj)                (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_DROP_ACTION, ClutterDropAction))
 | 
			
		||||
#define CLUTTER_IS_DROP_ACTION(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_DROP_ACTION))
 | 
			
		||||
#define CLUTTER_DROP_ACTION_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_DROP_ACTION, ClutterDropActionClass))
 | 
			
		||||
#define CLUTTER_IS_DROP_ACTION_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_DROP_ACTION))
 | 
			
		||||
#define CLUTTER_DROP_ACTION_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_DROP_ACTION, ClutterDropActionClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _ClutterDropAction               ClutterDropAction;
 | 
			
		||||
typedef struct _ClutterDropActionPrivate        ClutterDropActionPrivate;
 | 
			
		||||
typedef struct _ClutterDropActionClass          ClutterDropActionClass;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ClutterDropAction:
 | 
			
		||||
 *
 | 
			
		||||
 * The #ClutterDropAction structure contains only
 | 
			
		||||
 * private data and should be accessed using the provided API.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.8
 | 
			
		||||
 */
 | 
			
		||||
struct _ClutterDropAction
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  ClutterAction parent_instance;
 | 
			
		||||
 | 
			
		||||
  ClutterDropActionPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ClutterDropActionClass:
 | 
			
		||||
 * @can_drop: class handler for the #ClutterDropAction::can-drop signal
 | 
			
		||||
 * @over_in: class handler for the #ClutterDropAction::over-in signal
 | 
			
		||||
 * @over_out: class handler for the #ClutterDropAction::over-out signal
 | 
			
		||||
 * @drop: class handler for the #ClutterDropAction::drop signal
 | 
			
		||||
 *
 | 
			
		||||
 * The #ClutterDropActionClass structure contains
 | 
			
		||||
 * only private data.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.8
 | 
			
		||||
 */
 | 
			
		||||
struct _ClutterDropActionClass
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  ClutterActionClass parent_class;
 | 
			
		||||
 | 
			
		||||
  /*< public >*/
 | 
			
		||||
  gboolean (* can_drop) (ClutterDropAction *action,
 | 
			
		||||
                         ClutterActor      *actor,
 | 
			
		||||
                         gfloat             event_x,
 | 
			
		||||
                         gfloat             event_y);
 | 
			
		||||
 | 
			
		||||
  void     (* over_in)  (ClutterDropAction *action,
 | 
			
		||||
                         ClutterActor      *actor);
 | 
			
		||||
  void     (* over_out) (ClutterDropAction *action,
 | 
			
		||||
                         ClutterActor      *actor);
 | 
			
		||||
 | 
			
		||||
  void     (* drop)     (ClutterDropAction *action,
 | 
			
		||||
                         ClutterActor      *actor,
 | 
			
		||||
                         gfloat             event_x,
 | 
			
		||||
                         gfloat             event_y);
 | 
			
		||||
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  void (*_clutter_drop_action1) (void);
 | 
			
		||||
  void (*_clutter_drop_action2) (void);
 | 
			
		||||
  void (*_clutter_drop_action3) (void);
 | 
			
		||||
  void (*_clutter_drop_action4) (void);
 | 
			
		||||
  void (*_clutter_drop_action5) (void);
 | 
			
		||||
  void (*_clutter_drop_action6) (void);
 | 
			
		||||
  void (*_clutter_drop_action7) (void);
 | 
			
		||||
  void (*_clutter_drop_action8) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
GType clutter_drop_action_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
ClutterAction *         clutter_drop_action_new         (void);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __CLUTTER_DROP_ACTION_H__ */
 | 
			
		||||
@@ -230,28 +230,26 @@ clutter_effect_real_pick (ClutterEffect      *effect,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_effect_notify (GObject    *gobject,
 | 
			
		||||
                       GParamSpec *pspec)
 | 
			
		||||
clutter_effect_set_enabled (ClutterActorMeta *meta,
 | 
			
		||||
                            gboolean          is_enabled)
 | 
			
		||||
{
 | 
			
		||||
  if (strcmp (pspec->name, "enabled") == 0)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterActorMeta *meta = CLUTTER_ACTOR_META (gobject);
 | 
			
		||||
      ClutterActor *actor = clutter_actor_meta_get_actor (meta);
 | 
			
		||||
  ClutterActorMetaClass *parent_class =
 | 
			
		||||
    CLUTTER_ACTOR_META_CLASS (clutter_effect_parent_class);
 | 
			
		||||
  ClutterActor *actor;
 | 
			
		||||
 | 
			
		||||
      if (actor != NULL)
 | 
			
		||||
        clutter_actor_queue_redraw (actor);
 | 
			
		||||
    }
 | 
			
		||||
  actor = clutter_actor_meta_get_actor (meta);
 | 
			
		||||
  if (actor)
 | 
			
		||||
    clutter_actor_queue_redraw (actor);
 | 
			
		||||
 | 
			
		||||
  if (G_OBJECT_CLASS (clutter_effect_parent_class)->notify != NULL)
 | 
			
		||||
    G_OBJECT_CLASS (clutter_effect_parent_class)->notify (gobject, pspec);
 | 
			
		||||
  parent_class->set_enabled (meta, is_enabled);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_effect_class_init (ClutterEffectClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  ClutterActorMetaClass *actor_meta_class = CLUTTER_ACTOR_META_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  gobject_class->notify = clutter_effect_notify;
 | 
			
		||||
  actor_meta_class->set_enabled = clutter_effect_set_enabled;
 | 
			
		||||
 | 
			
		||||
  klass->pre_paint = clutter_effect_real_pre_paint;
 | 
			
		||||
  klass->post_paint = clutter_effect_real_post_paint;
 | 
			
		||||
 
 | 
			
		||||
@@ -556,6 +556,21 @@ clutter_gesture_action_set_actor (ClutterActorMeta *meta,
 | 
			
		||||
  meta_class->set_actor (meta, actor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_gesture_action_set_enabled (ClutterActorMeta *meta,
 | 
			
		||||
                                    gboolean          is_enabled)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorMetaClass *meta_class =
 | 
			
		||||
    CLUTTER_ACTOR_META_CLASS (clutter_gesture_action_parent_class);
 | 
			
		||||
  ClutterGestureAction *gesture_action = CLUTTER_GESTURE_ACTION (meta);
 | 
			
		||||
  ClutterGestureActionPrivate *priv = gesture_action->priv;
 | 
			
		||||
 | 
			
		||||
  if (!is_enabled && priv->in_gesture)
 | 
			
		||||
    cancel_gesture (gesture_action);
 | 
			
		||||
 | 
			
		||||
  meta_class->set_enabled (meta, is_enabled);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
default_event_handler (ClutterGestureAction *action,
 | 
			
		||||
                       ClutterActor *actor)
 | 
			
		||||
@@ -654,6 +669,7 @@ clutter_gesture_action_class_init (ClutterGestureActionClass *klass)
 | 
			
		||||
  gobject_class->get_property = clutter_gesture_action_get_property;
 | 
			
		||||
 | 
			
		||||
  meta_class->set_actor = clutter_gesture_action_set_actor;
 | 
			
		||||
  meta_class->set_enabled = clutter_gesture_action_set_enabled;
 | 
			
		||||
 | 
			
		||||
  klass->gesture_begin = default_event_handler;
 | 
			
		||||
  klass->gesture_progress = default_event_handler;
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@ void clutter_input_focus_focus_out (ClutterInputFocus  *focus);
 | 
			
		||||
void clutter_input_focus_commit (ClutterInputFocus *focus,
 | 
			
		||||
                                 const gchar       *text);
 | 
			
		||||
void clutter_input_focus_delete_surrounding (ClutterInputFocus *focus,
 | 
			
		||||
                                             guint              offset,
 | 
			
		||||
                                             int                offset,
 | 
			
		||||
                                             guint              len);
 | 
			
		||||
void clutter_input_focus_request_surrounding (ClutterInputFocus *focus);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -217,7 +217,7 @@ clutter_input_focus_commit (ClutterInputFocus *focus,
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_input_focus_delete_surrounding (ClutterInputFocus *focus,
 | 
			
		||||
                                        guint              offset,
 | 
			
		||||
                                        int                offset,
 | 
			
		||||
                                        guint              len)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus));
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@ struct _ClutterInputFocusClass
 | 
			
		||||
 | 
			
		||||
  void (* request_surrounding) (ClutterInputFocus *focus);
 | 
			
		||||
  void (* delete_surrounding)  (ClutterInputFocus *focus,
 | 
			
		||||
                                guint              offset,
 | 
			
		||||
                                int                offset,
 | 
			
		||||
                                guint              len);
 | 
			
		||||
  void (* commit_text) (ClutterInputFocus *focus,
 | 
			
		||||
                        const gchar       *text);
 | 
			
		||||
 
 | 
			
		||||
@@ -168,7 +168,7 @@ clutter_input_method_class_init (ClutterInputMethodClass *klass)
 | 
			
		||||
                  G_TYPE_FROM_CLASS (object_class),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  0, NULL, NULL, NULL,
 | 
			
		||||
                  G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
 | 
			
		||||
                  G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_UINT);
 | 
			
		||||
  signals[REQUEST_SURROUNDING] =
 | 
			
		||||
    g_signal_new ("request-surrounding",
 | 
			
		||||
                  G_TYPE_FROM_CLASS (object_class),
 | 
			
		||||
@@ -292,7 +292,7 @@ clutter_input_method_commit (ClutterInputMethod *im,
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_input_method_delete_surrounding (ClutterInputMethod *im,
 | 
			
		||||
                                         guint               offset,
 | 
			
		||||
                                         int                 offset,
 | 
			
		||||
                                         guint               len)
 | 
			
		||||
{
 | 
			
		||||
  ClutterInputMethodPrivate *priv;
 | 
			
		||||
 
 | 
			
		||||
@@ -68,7 +68,7 @@ void clutter_input_method_commit (ClutterInputMethod *im,
 | 
			
		||||
                                  const gchar        *text);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void clutter_input_method_delete_surrounding (ClutterInputMethod *im,
 | 
			
		||||
                                              guint               offset,
 | 
			
		||||
                                              int                 offset,
 | 
			
		||||
                                              guint               len);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void clutter_input_method_request_surrounding (ClutterInputMethod *im);
 | 
			
		||||
 
 | 
			
		||||
@@ -29,10 +29,10 @@
 | 
			
		||||
 * of #ClutterMasterClock.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <cogl/cogl-trace.h>
 | 
			
		||||
 | 
			
		||||
#include "clutter-build-config.h"
 | 
			
		||||
 | 
			
		||||
#include <cogl/cogl.h>
 | 
			
		||||
 | 
			
		||||
#include "clutter-master-clock.h"
 | 
			
		||||
#include "clutter-master-clock-default.h"
 | 
			
		||||
#include "clutter-debug.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,9 @@
 | 
			
		||||
#include "cogl/clutter-stage-cogl.h"
 | 
			
		||||
#include "clutter/x11/clutter-backend-x11.h"
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
GList * clutter_stage_peek_stage_views (ClutterStage *stage);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void clutter_set_custom_backend_func (ClutterBackend *(* func) (void));
 | 
			
		||||
 | 
			
		||||
@@ -48,6 +51,23 @@ void clutter_stage_capture_into (ClutterStage          *stage,
 | 
			
		||||
                                 cairo_rectangle_int_t *rect,
 | 
			
		||||
                                 uint8_t               *data);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void clutter_stage_paint_to_framebuffer (ClutterStage                *stage,
 | 
			
		||||
                                         CoglFramebuffer             *framebuffer,
 | 
			
		||||
                                         const cairo_rectangle_int_t *rect,
 | 
			
		||||
                                         float                        scale,
 | 
			
		||||
                                         ClutterPaintFlag             paint_flags);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
gboolean clutter_stage_paint_to_buffer (ClutterStage                 *stage,
 | 
			
		||||
                                        const cairo_rectangle_int_t  *rect,
 | 
			
		||||
                                        float                         scale,
 | 
			
		||||
                                        uint8_t                      *data,
 | 
			
		||||
                                        int                           stride,
 | 
			
		||||
                                        CoglPixelFormat               format,
 | 
			
		||||
                                        ClutterPaintFlag              paint_flags,
 | 
			
		||||
                                        GError                      **error);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void clutter_stage_freeze_updates (ClutterStage *stage);
 | 
			
		||||
 | 
			
		||||
@@ -57,9 +77,16 @@ void clutter_stage_thaw_updates (ClutterStage *stage);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void clutter_stage_update_resource_scales (ClutterStage *stage);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void clutter_stage_view_assign_next_scanout (ClutterStageView *stage_view,
 | 
			
		||||
                                             CoglScanout      *scanout);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
gboolean clutter_actor_has_damage (ClutterActor *actor);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
gboolean clutter_actor_has_transitions (ClutterActor *actor);
 | 
			
		||||
 | 
			
		||||
#undef __CLUTTER_H_INSIDE__
 | 
			
		||||
 | 
			
		||||
#endif /* __CLUTTER_MUTTER_H__ */
 | 
			
		||||
 
 | 
			
		||||
@@ -81,7 +81,7 @@
 | 
			
		||||
struct _ClutterOffscreenEffectPrivate
 | 
			
		||||
{
 | 
			
		||||
  CoglHandle offscreen;
 | 
			
		||||
  CoglPipeline *target;
 | 
			
		||||
  CoglPipeline *pipeline;
 | 
			
		||||
  CoglHandle texture;
 | 
			
		||||
 | 
			
		||||
  ClutterActor *actor;
 | 
			
		||||
@@ -140,7 +140,7 @@ ensure_pipeline_filter_for_scale (ClutterOffscreenEffect *self,
 | 
			
		||||
{
 | 
			
		||||
  CoglPipelineFilter filter;
 | 
			
		||||
 | 
			
		||||
  if (!self->priv->target)
 | 
			
		||||
  if (!self->priv->pipeline)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  /* If no fractional scaling is set, we're always going to render the texture
 | 
			
		||||
@@ -154,7 +154,7 @@ ensure_pipeline_filter_for_scale (ClutterOffscreenEffect *self,
 | 
			
		||||
  else
 | 
			
		||||
    filter = COGL_PIPELINE_FILTER_LINEAR;
 | 
			
		||||
 | 
			
		||||
  cogl_pipeline_set_layer_filters (self->priv->target, 0 /* layer_index */,
 | 
			
		||||
  cogl_pipeline_set_layer_filters (self->priv->pipeline, 0 /* layer_index */,
 | 
			
		||||
                                   filter, filter);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -185,12 +185,12 @@ update_fbo (ClutterEffect *effect,
 | 
			
		||||
    return TRUE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (priv->target == NULL)
 | 
			
		||||
  if (priv->pipeline == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      CoglContext *ctx =
 | 
			
		||||
        clutter_backend_get_cogl_context (clutter_get_default_backend ());
 | 
			
		||||
 | 
			
		||||
      priv->target = cogl_pipeline_new (ctx);
 | 
			
		||||
      priv->pipeline = cogl_pipeline_new (ctx);
 | 
			
		||||
      ensure_pipeline_filter_for_scale (self, resource_scale);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -202,7 +202,7 @@ update_fbo (ClutterEffect *effect,
 | 
			
		||||
  if (priv->texture == NULL)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  cogl_pipeline_set_layer_texture (priv->target, 0, priv->texture);
 | 
			
		||||
  cogl_pipeline_set_layer_texture (priv->pipeline, 0, priv->texture);
 | 
			
		||||
 | 
			
		||||
  priv->target_width = target_width;
 | 
			
		||||
  priv->target_height = target_height;
 | 
			
		||||
@@ -212,8 +212,8 @@ update_fbo (ClutterEffect *effect,
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("%s: Unable to create an Offscreen buffer", G_STRLOC);
 | 
			
		||||
 | 
			
		||||
      cogl_object_unref (priv->target);
 | 
			
		||||
      priv->target = NULL;
 | 
			
		||||
      cogl_object_unref (priv->pipeline);
 | 
			
		||||
      priv->pipeline = NULL;
 | 
			
		||||
 | 
			
		||||
      priv->target_width = 0;
 | 
			
		||||
      priv->target_height = 0;
 | 
			
		||||
@@ -380,7 +380,7 @@ clutter_offscreen_effect_real_paint_target (ClutterOffscreenEffect *effect,
 | 
			
		||||
 | 
			
		||||
  paint_opacity = clutter_actor_get_paint_opacity (priv->actor);
 | 
			
		||||
 | 
			
		||||
  cogl_pipeline_set_color4ub (priv->target,
 | 
			
		||||
  cogl_pipeline_set_color4ub (priv->pipeline,
 | 
			
		||||
                              paint_opacity,
 | 
			
		||||
                              paint_opacity,
 | 
			
		||||
                              paint_opacity,
 | 
			
		||||
@@ -392,7 +392,7 @@ clutter_offscreen_effect_real_paint_target (ClutterOffscreenEffect *effect,
 | 
			
		||||
   * hadn't been redirected offscreen.
 | 
			
		||||
   */
 | 
			
		||||
  cogl_framebuffer_draw_textured_rectangle (framebuffer,
 | 
			
		||||
                                            priv->target,
 | 
			
		||||
                                            priv->pipeline,
 | 
			
		||||
                                            0, 0,
 | 
			
		||||
                                            cogl_texture_get_width (priv->texture),
 | 
			
		||||
                                            cogl_texture_get_height (priv->texture),
 | 
			
		||||
@@ -446,13 +446,16 @@ clutter_offscreen_effect_post_paint (ClutterEffect       *effect,
 | 
			
		||||
  ClutterOffscreenEffectPrivate *priv = self->priv;
 | 
			
		||||
  CoglFramebuffer *framebuffer;
 | 
			
		||||
 | 
			
		||||
  if (priv->offscreen == NULL ||
 | 
			
		||||
      priv->target == NULL ||
 | 
			
		||||
      priv->actor == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
  g_warn_if_fail (priv->offscreen);
 | 
			
		||||
  g_warn_if_fail (priv->pipeline);
 | 
			
		||||
  g_warn_if_fail (priv->actor);
 | 
			
		||||
 | 
			
		||||
  /* Restore the previous opacity override */
 | 
			
		||||
  clutter_actor_set_opacity_override (priv->actor, priv->old_opacity_override);
 | 
			
		||||
  if (priv->actor)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_set_opacity_override (priv->actor,
 | 
			
		||||
                                          priv->old_opacity_override);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  framebuffer = clutter_paint_context_get_framebuffer (paint_context);
 | 
			
		||||
  cogl_framebuffer_pop_matrix (framebuffer);
 | 
			
		||||
@@ -498,16 +501,17 @@ clutter_offscreen_effect_paint (ClutterEffect           *effect,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_offscreen_effect_notify (GObject    *gobject,
 | 
			
		||||
                                 GParamSpec *pspec)
 | 
			
		||||
clutter_offscreen_effect_set_enabled (ClutterActorMeta *meta,
 | 
			
		||||
                                      gboolean          is_enabled)
 | 
			
		||||
{
 | 
			
		||||
  ClutterOffscreenEffect *offscreen_effect = CLUTTER_OFFSCREEN_EFFECT (gobject);
 | 
			
		||||
  ClutterActorMetaClass *parent_class =
 | 
			
		||||
    CLUTTER_ACTOR_META_CLASS (clutter_offscreen_effect_parent_class);
 | 
			
		||||
  ClutterOffscreenEffect *offscreen_effect = CLUTTER_OFFSCREEN_EFFECT (meta);
 | 
			
		||||
  ClutterOffscreenEffectPrivate *priv = offscreen_effect->priv;
 | 
			
		||||
 | 
			
		||||
  if (strcmp (pspec->name, "enabled") == 0)
 | 
			
		||||
    g_clear_pointer (&priv->offscreen, cogl_object_unref);
 | 
			
		||||
  g_clear_pointer (&priv->offscreen, cogl_object_unref);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (clutter_offscreen_effect_parent_class)->notify (gobject, pspec);
 | 
			
		||||
  parent_class->set_enabled (meta, is_enabled);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -518,7 +522,7 @@ clutter_offscreen_effect_finalize (GObject *gobject)
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&priv->offscreen, cogl_object_unref);
 | 
			
		||||
  g_clear_pointer (&priv->texture, cogl_object_unref);
 | 
			
		||||
  g_clear_pointer (&priv->target, cogl_object_unref);
 | 
			
		||||
  g_clear_pointer (&priv->pipeline, cogl_object_unref);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (clutter_offscreen_effect_parent_class)->finalize (gobject);
 | 
			
		||||
}
 | 
			
		||||
@@ -534,13 +538,13 @@ clutter_offscreen_effect_class_init (ClutterOffscreenEffectClass *klass)
 | 
			
		||||
  klass->paint_target = clutter_offscreen_effect_real_paint_target;
 | 
			
		||||
 | 
			
		||||
  meta_class->set_actor = clutter_offscreen_effect_set_actor;
 | 
			
		||||
  meta_class->set_enabled = clutter_offscreen_effect_set_enabled;
 | 
			
		||||
 | 
			
		||||
  effect_class->pre_paint = clutter_offscreen_effect_pre_paint;
 | 
			
		||||
  effect_class->post_paint = clutter_offscreen_effect_post_paint;
 | 
			
		||||
  effect_class->paint = clutter_offscreen_effect_paint;
 | 
			
		||||
 | 
			
		||||
  gobject_class->finalize = clutter_offscreen_effect_finalize;
 | 
			
		||||
  gobject_class->notify = clutter_offscreen_effect_notify;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -600,7 +604,7 @@ clutter_offscreen_effect_get_target (ClutterOffscreenEffect *effect)
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_OFFSCREEN_EFFECT (effect),
 | 
			
		||||
                        NULL);
 | 
			
		||||
 | 
			
		||||
  return (CoglMaterial *)effect->priv->target;
 | 
			
		||||
  return (CoglMaterial *)effect->priv->pipeline;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,8 @@
 | 
			
		||||
#include "clutter-paint-context.h"
 | 
			
		||||
 | 
			
		||||
ClutterPaintContext * clutter_paint_context_new_for_view (ClutterStageView     *view,
 | 
			
		||||
                                                          const cairo_region_t *redraw_clip);
 | 
			
		||||
                                                          const cairo_region_t *redraw_clip,
 | 
			
		||||
                                                          ClutterPaintFlag      paint_flags);
 | 
			
		||||
 | 
			
		||||
gboolean clutter_paint_context_is_drawing_off_stage (ClutterPaintContext *paint_context);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,8 @@ struct _ClutterPaintContext
 | 
			
		||||
{
 | 
			
		||||
  grefcount ref_count;
 | 
			
		||||
 | 
			
		||||
  ClutterPaintFlag paint_flags;
 | 
			
		||||
 | 
			
		||||
  GList *framebuffers;
 | 
			
		||||
 | 
			
		||||
  ClutterStageView *view;
 | 
			
		||||
@@ -36,7 +38,8 @@ G_DEFINE_BOXED_TYPE (ClutterPaintContext, clutter_paint_context,
 | 
			
		||||
 | 
			
		||||
ClutterPaintContext *
 | 
			
		||||
clutter_paint_context_new_for_view (ClutterStageView     *view,
 | 
			
		||||
                                    const cairo_region_t *redraw_clip)
 | 
			
		||||
                                    const cairo_region_t *redraw_clip,
 | 
			
		||||
                                    ClutterPaintFlag      paint_flags)
 | 
			
		||||
{
 | 
			
		||||
  ClutterPaintContext *paint_context;
 | 
			
		||||
  CoglFramebuffer *framebuffer;
 | 
			
		||||
@@ -45,6 +48,7 @@ clutter_paint_context_new_for_view (ClutterStageView     *view,
 | 
			
		||||
  g_ref_count_init (&paint_context->ref_count);
 | 
			
		||||
  paint_context->view = view;
 | 
			
		||||
  paint_context->redraw_clip = cairo_region_copy (redraw_clip);
 | 
			
		||||
  paint_context->paint_flags = paint_flags;
 | 
			
		||||
 | 
			
		||||
  framebuffer = clutter_stage_view_get_framebuffer (view);
 | 
			
		||||
  clutter_paint_context_push_framebuffer (paint_context, framebuffer);
 | 
			
		||||
@@ -56,12 +60,16 @@ clutter_paint_context_new_for_view (ClutterStageView     *view,
 | 
			
		||||
 * clutter_paint_context_new_for_framebuffer: (skip)
 | 
			
		||||
 */
 | 
			
		||||
ClutterPaintContext *
 | 
			
		||||
clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer)
 | 
			
		||||
clutter_paint_context_new_for_framebuffer (CoglFramebuffer      *framebuffer,
 | 
			
		||||
                                           const cairo_region_t *redraw_clip,
 | 
			
		||||
                                           ClutterPaintFlag      paint_flags)
 | 
			
		||||
{
 | 
			
		||||
  ClutterPaintContext *paint_context;
 | 
			
		||||
 | 
			
		||||
  paint_context = g_new0 (ClutterPaintContext, 1);
 | 
			
		||||
  g_ref_count_init (&paint_context->ref_count);
 | 
			
		||||
  paint_context->redraw_clip = cairo_region_copy (redraw_clip);
 | 
			
		||||
  paint_context->paint_flags = paint_flags;
 | 
			
		||||
 | 
			
		||||
  clutter_paint_context_push_framebuffer (paint_context, framebuffer);
 | 
			
		||||
 | 
			
		||||
@@ -170,3 +178,12 @@ clutter_paint_context_is_drawing_off_stage (ClutterPaintContext *paint_context)
 | 
			
		||||
 | 
			
		||||
  return !paint_context->view;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_paint_context_get_paint_flags: (skip)
 | 
			
		||||
 */
 | 
			
		||||
ClutterPaintFlag
 | 
			
		||||
clutter_paint_context_get_paint_flags (ClutterPaintContext *paint_context)
 | 
			
		||||
{
 | 
			
		||||
  return paint_context->paint_flags;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -29,13 +29,21 @@
 | 
			
		||||
 | 
			
		||||
typedef struct _ClutterPaintContext ClutterPaintContext;
 | 
			
		||||
 | 
			
		||||
typedef enum _ClutterPaintFlag
 | 
			
		||||
{
 | 
			
		||||
  CLUTTER_PAINT_FLAG_NONE = 0,
 | 
			
		||||
  CLUTTER_PAINT_FLAG_NO_CURSORS = 1 << 0,
 | 
			
		||||
} ClutterPaintFlag;
 | 
			
		||||
 | 
			
		||||
#define CLUTTER_TYPE_PAINT_CONTEXT (clutter_paint_context_get_type ())
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
GType clutter_paint_context_get_type (void);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
ClutterPaintContext * clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer);
 | 
			
		||||
ClutterPaintContext * clutter_paint_context_new_for_framebuffer (CoglFramebuffer      *framebuffer,
 | 
			
		||||
                                                                 const cairo_region_t *redraw_clip,
 | 
			
		||||
                                                                 ClutterPaintFlag      paint_flags);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
ClutterPaintContext * clutter_paint_context_ref (ClutterPaintContext *paint_context);
 | 
			
		||||
@@ -62,4 +70,7 @@ void clutter_paint_context_pop_framebuffer (ClutterPaintContext *paint_context);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
const cairo_region_t * clutter_paint_context_get_redraw_clip (ClutterPaintContext *paint_context);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
ClutterPaintFlag clutter_paint_context_get_paint_flags (ClutterPaintContext *paint_context);
 | 
			
		||||
 | 
			
		||||
#endif /* CLUTTER_PAINT_CONTEXT_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -83,7 +83,6 @@ typedef enum
 | 
			
		||||
  PAINT_OP_INVALID = 0,
 | 
			
		||||
  PAINT_OP_TEX_RECT,
 | 
			
		||||
  PAINT_OP_MULTITEX_RECT,
 | 
			
		||||
  PAINT_OP_PATH,
 | 
			
		||||
  PAINT_OP_PRIMITIVE
 | 
			
		||||
} PaintOpCode;
 | 
			
		||||
 | 
			
		||||
@@ -96,8 +95,6 @@ struct _ClutterPaintOperation
 | 
			
		||||
  union {
 | 
			
		||||
    float texrect[8];
 | 
			
		||||
 | 
			
		||||
    CoglPath *path;
 | 
			
		||||
 | 
			
		||||
    CoglPrimitive *primitive;
 | 
			
		||||
  } op;
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -782,11 +782,6 @@ clutter_paint_operation_clear (ClutterPaintOperation *op)
 | 
			
		||||
        g_array_unref (op->multitex_coords);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PAINT_OP_PATH:
 | 
			
		||||
      if (op->op.path != NULL)
 | 
			
		||||
        cogl_object_unref (op->op.path);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PAINT_OP_PRIMITIVE:
 | 
			
		||||
      if (op->op.primitive != NULL)
 | 
			
		||||
        cogl_object_unref (op->op.primitive);
 | 
			
		||||
@@ -836,16 +831,6 @@ clutter_paint_op_init_multitex_rect (ClutterPaintOperation *op,
 | 
			
		||||
  op->op.texrect[3] = rect->y2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
clutter_paint_op_init_path (ClutterPaintOperation *op,
 | 
			
		||||
                            CoglPath              *path)
 | 
			
		||||
{
 | 
			
		||||
  clutter_paint_operation_clear (op);
 | 
			
		||||
 | 
			
		||||
  op->opcode = PAINT_OP_PATH;
 | 
			
		||||
  op->op.path = cogl_object_ref (path);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
clutter_paint_op_init_primitive (ClutterPaintOperation *op,
 | 
			
		||||
                                 CoglPrimitive         *primitive)
 | 
			
		||||
@@ -950,34 +935,6 @@ clutter_paint_node_add_multitexture_rectangle (ClutterPaintNode      *node,
 | 
			
		||||
  g_array_append_val (node->operations, operation);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_paint_node_add_path: (skip)
 | 
			
		||||
 * @node: a #ClutterPaintNode
 | 
			
		||||
 * @path: a Cogl path
 | 
			
		||||
 *
 | 
			
		||||
 * Adds a region described as a path to the @node.
 | 
			
		||||
 *
 | 
			
		||||
 * This function acquires a reference on the passed @path, so it
 | 
			
		||||
 * is safe to call cogl_object_unref() when it returns.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.10
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
clutter_paint_node_add_path (ClutterPaintNode *node,
 | 
			
		||||
                             CoglPath         *path)
 | 
			
		||||
{
 | 
			
		||||
  ClutterPaintOperation operation = PAINT_OP_INIT;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_PAINT_NODE (node));
 | 
			
		||||
  g_return_if_fail (cogl_is_path (path));
 | 
			
		||||
 | 
			
		||||
  clutter_paint_node_maybe_init_operations (node);
 | 
			
		||||
 | 
			
		||||
  clutter_paint_op_init_path (&operation, path);
 | 
			
		||||
  g_array_append_val (node->operations, operation);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_paint_node_add_primitive: (skip)
 | 
			
		||||
 * @node: a #ClutterPaintNode
 | 
			
		||||
@@ -1114,11 +1071,6 @@ clutter_paint_node_to_json (ClutterPaintNode *node)
 | 
			
		||||
              json_builder_end_array (builder);
 | 
			
		||||
              break;
 | 
			
		||||
 | 
			
		||||
            case PAINT_OP_PATH:
 | 
			
		||||
              json_builder_set_member_name (builder, "path");
 | 
			
		||||
              json_builder_add_int_value (builder, (intptr_t) op->op.path);
 | 
			
		||||
              break;
 | 
			
		||||
 | 
			
		||||
            case PAINT_OP_PRIMITIVE:
 | 
			
		||||
              json_builder_set_member_name (builder, "primitive");
 | 
			
		||||
              json_builder_add_int_value (builder, (intptr_t) op->op.primitive);
 | 
			
		||||
 
 | 
			
		||||
@@ -84,9 +84,6 @@ void                   clutter_paint_node_add_multitexture_rectangle   (ClutterP
 | 
			
		||||
                                                                        unsigned int            text_coords_len);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void                    clutter_paint_node_add_path                     (ClutterPaintNode      *node,
 | 
			
		||||
                                                                         CoglPath              *path);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void                    clutter_paint_node_add_primitive                (ClutterPaintNode      *node,
 | 
			
		||||
                                                                         CoglPrimitive         *primitive);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -477,10 +477,6 @@ clutter_pipeline_node_draw (ClutterPaintNode    *node,
 | 
			
		||||
                                                         op->multitex_coords->len);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case PAINT_OP_PATH:
 | 
			
		||||
          cogl_framebuffer_fill_path (fb, pnode->pipeline, op->op.path);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case PAINT_OP_PRIMITIVE:
 | 
			
		||||
          cogl_framebuffer_draw_primitive (fb,
 | 
			
		||||
                                           pnode->pipeline,
 | 
			
		||||
@@ -876,7 +872,6 @@ clutter_text_node_draw (ClutterPaintNode    *node,
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case PAINT_OP_MULTITEX_RECT:
 | 
			
		||||
        case PAINT_OP_PATH:
 | 
			
		||||
        case PAINT_OP_PRIMITIVE:
 | 
			
		||||
        case PAINT_OP_INVALID:
 | 
			
		||||
          break;
 | 
			
		||||
@@ -1037,11 +1032,6 @@ clutter_clip_node_pre_draw (ClutterPaintNode    *node,
 | 
			
		||||
          retval = TRUE;
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case PAINT_OP_PATH:
 | 
			
		||||
          cogl_framebuffer_push_path_clip (fb, op->op.path);
 | 
			
		||||
          retval = TRUE;
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case PAINT_OP_MULTITEX_RECT:
 | 
			
		||||
        case PAINT_OP_PRIMITIVE:
 | 
			
		||||
        case PAINT_OP_INVALID:
 | 
			
		||||
@@ -1072,7 +1062,6 @@ clutter_clip_node_post_draw (ClutterPaintNode    *node,
 | 
			
		||||
 | 
			
		||||
      switch (op->opcode)
 | 
			
		||||
        {
 | 
			
		||||
        case PAINT_OP_PATH:
 | 
			
		||||
        case PAINT_OP_TEX_RECT:
 | 
			
		||||
          cogl_framebuffer_pop_clip (fb);
 | 
			
		||||
          break;
 | 
			
		||||
@@ -1242,9 +1231,8 @@ struct _ClutterLayerNode
 | 
			
		||||
  float fbo_width;
 | 
			
		||||
  float fbo_height;
 | 
			
		||||
 | 
			
		||||
  CoglPipeline *state;
 | 
			
		||||
  CoglPipeline *pipeline;
 | 
			
		||||
  CoglFramebuffer *offscreen;
 | 
			
		||||
  CoglTexture *texture;
 | 
			
		||||
 | 
			
		||||
  guint8 opacity;
 | 
			
		||||
};
 | 
			
		||||
@@ -1334,7 +1322,7 @@ clutter_layer_node_post_draw (ClutterPaintNode    *node,
 | 
			
		||||
        case PAINT_OP_TEX_RECT:
 | 
			
		||||
          /* now we need to paint the texture */
 | 
			
		||||
          cogl_framebuffer_draw_textured_rectangle (fb,
 | 
			
		||||
                                                    lnode->state,
 | 
			
		||||
                                                    lnode->pipeline,
 | 
			
		||||
                                                    op->op.texrect[0],
 | 
			
		||||
                                                    op->op.texrect[1],
 | 
			
		||||
                                                    op->op.texrect[2],
 | 
			
		||||
@@ -1347,7 +1335,7 @@ clutter_layer_node_post_draw (ClutterPaintNode    *node,
 | 
			
		||||
 | 
			
		||||
        case PAINT_OP_MULTITEX_RECT:
 | 
			
		||||
          cogl_framebuffer_draw_multitextured_rectangle (fb,
 | 
			
		||||
                                                         lnode->state,
 | 
			
		||||
                                                         lnode->pipeline,
 | 
			
		||||
                                                         op->op.texrect[0],
 | 
			
		||||
                                                         op->op.texrect[1],
 | 
			
		||||
                                                         op->op.texrect[2],
 | 
			
		||||
@@ -1356,12 +1344,10 @@ clutter_layer_node_post_draw (ClutterPaintNode    *node,
 | 
			
		||||
                                                         op->multitex_coords->len);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case PAINT_OP_PATH:
 | 
			
		||||
          cogl_framebuffer_fill_path (fb, lnode->state, op->op.path);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case PAINT_OP_PRIMITIVE:
 | 
			
		||||
          cogl_framebuffer_draw_primitive (fb, lnode->state, op->op.primitive);
 | 
			
		||||
          cogl_framebuffer_draw_primitive (fb,
 | 
			
		||||
                                           lnode->pipeline,
 | 
			
		||||
                                           op->op.primitive);
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -1372,8 +1358,8 @@ clutter_layer_node_finalize (ClutterPaintNode *node)
 | 
			
		||||
{
 | 
			
		||||
  ClutterLayerNode *lnode = CLUTTER_LAYER_NODE (node);
 | 
			
		||||
 | 
			
		||||
  if (lnode->state != NULL)
 | 
			
		||||
    cogl_object_unref (lnode->state);
 | 
			
		||||
  if (lnode->pipeline != NULL)
 | 
			
		||||
    cogl_object_unref (lnode->pipeline);
 | 
			
		||||
 | 
			
		||||
  if (lnode->offscreen != NULL)
 | 
			
		||||
    cogl_object_unref (lnode->offscreen);
 | 
			
		||||
@@ -1425,6 +1411,8 @@ clutter_layer_node_new (const CoglMatrix        *projection,
 | 
			
		||||
                        guint8                   opacity)
 | 
			
		||||
{
 | 
			
		||||
  ClutterLayerNode *res;
 | 
			
		||||
  CoglContext *context;
 | 
			
		||||
  CoglTexture *texture;
 | 
			
		||||
  CoglColor color;
 | 
			
		||||
 | 
			
		||||
  res = _clutter_paint_node_create (CLUTTER_TYPE_LAYER_NODE);
 | 
			
		||||
@@ -1436,19 +1424,17 @@ clutter_layer_node_new (const CoglMatrix        *projection,
 | 
			
		||||
  res->opacity = opacity;
 | 
			
		||||
 | 
			
		||||
  /* the texture backing the FBO */
 | 
			
		||||
  res->texture = cogl_texture_new_with_size (MAX (res->fbo_width, 1),
 | 
			
		||||
                                             MAX (res->fbo_height, 1),
 | 
			
		||||
                                             COGL_TEXTURE_NO_SLICING,
 | 
			
		||||
                                             COGL_PIXEL_FORMAT_RGBA_8888_PRE);
 | 
			
		||||
  context = clutter_backend_get_cogl_context (clutter_get_default_backend ());
 | 
			
		||||
 | 
			
		||||
  res->offscreen = COGL_FRAMEBUFFER (cogl_offscreen_new_to_texture (res->texture));
 | 
			
		||||
  texture = cogl_texture_2d_new_with_size (context,
 | 
			
		||||
                                           MAX (res->fbo_width, 1),
 | 
			
		||||
                                           MAX (res->fbo_height, 1));
 | 
			
		||||
  cogl_texture_set_premultiplied (texture, TRUE);
 | 
			
		||||
 | 
			
		||||
  res->offscreen = COGL_FRAMEBUFFER (cogl_offscreen_new_to_texture (texture));
 | 
			
		||||
  if (res->offscreen == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      g_critical ("%s: Unable to create an offscreen buffer", G_STRLOC);
 | 
			
		||||
 | 
			
		||||
      cogl_object_unref (res->texture);
 | 
			
		||||
      res->texture = NULL;
 | 
			
		||||
 | 
			
		||||
      goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -1458,14 +1444,15 @@ clutter_layer_node_new (const CoglMatrix        *projection,
 | 
			
		||||
   * interpolation filters because the texture is always
 | 
			
		||||
   * going to be painted at a 1:1 texel:pixel ratio
 | 
			
		||||
   */
 | 
			
		||||
  res->state = cogl_pipeline_copy (default_texture_pipeline);
 | 
			
		||||
  cogl_pipeline_set_layer_filters (res->state, 0,
 | 
			
		||||
  res->pipeline = cogl_pipeline_copy (default_texture_pipeline);
 | 
			
		||||
  cogl_pipeline_set_layer_filters (res->pipeline, 0,
 | 
			
		||||
                                   COGL_PIPELINE_FILTER_NEAREST,
 | 
			
		||||
                                   COGL_PIPELINE_FILTER_NEAREST);
 | 
			
		||||
  cogl_pipeline_set_layer_texture (res->state, 0, res->texture);
 | 
			
		||||
  cogl_pipeline_set_color (res->state, &color);
 | 
			
		||||
  cogl_object_unref (res->texture);
 | 
			
		||||
  cogl_pipeline_set_layer_texture (res->pipeline, 0, texture);
 | 
			
		||||
  cogl_pipeline_set_color (res->pipeline, &color);
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
  cogl_object_unref (texture);
 | 
			
		||||
 | 
			
		||||
  return (ClutterPaintNode *) res;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -139,8 +139,6 @@ void            _clutter_stage_presented                (ClutterStage      *stag
 | 
			
		||||
                                                         CoglFrameEvent     frame_event,
 | 
			
		||||
                                                         ClutterFrameInfo  *frame_info);
 | 
			
		||||
 | 
			
		||||
GList *         _clutter_stage_peek_stage_views         (ClutterStage *stage);
 | 
			
		||||
 | 
			
		||||
void            clutter_stage_queue_actor_relayout      (ClutterStage *stage,
 | 
			
		||||
                                                         ClutterActor *actor);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -43,4 +43,6 @@ const cairo_region_t * clutter_stage_view_peek_redraw_clip (ClutterStageView *vi
 | 
			
		||||
 | 
			
		||||
cairo_region_t * clutter_stage_view_take_redraw_clip (ClutterStageView *view);
 | 
			
		||||
 | 
			
		||||
CoglScanout * clutter_stage_view_take_scanout (ClutterStageView *view);
 | 
			
		||||
 | 
			
		||||
#endif /* __CLUTTER_STAGE_VIEW_PRIVATE_H__ */
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,8 @@
 | 
			
		||||
#include <math.h>
 | 
			
		||||
 | 
			
		||||
#include "clutter/clutter-private.h"
 | 
			
		||||
#include "clutter/clutter-mutter.h"
 | 
			
		||||
#include "cogl/cogl.h"
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
@@ -52,6 +54,8 @@ typedef struct _ClutterStageViewPrivate
 | 
			
		||||
  CoglOffscreen *shadowfb;
 | 
			
		||||
  CoglPipeline *shadowfb_pipeline;
 | 
			
		||||
 | 
			
		||||
  CoglScanout *next_scanout;
 | 
			
		||||
 | 
			
		||||
  gboolean has_redraw_clip;
 | 
			
		||||
  cairo_region_t *redraw_clip;
 | 
			
		||||
 | 
			
		||||
@@ -407,6 +411,25 @@ clutter_stage_default_get_offscreen_transformation_matrix (ClutterStageView *vie
 | 
			
		||||
  cogl_matrix_init_identity (matrix);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_stage_view_assign_next_scanout (ClutterStageView *view,
 | 
			
		||||
                                        CoglScanout      *scanout)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewPrivate *priv =
 | 
			
		||||
    clutter_stage_view_get_instance_private (view);
 | 
			
		||||
 | 
			
		||||
  g_set_object (&priv->next_scanout, scanout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CoglScanout *
 | 
			
		||||
clutter_stage_view_take_scanout (ClutterStageView *view)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewPrivate *priv =
 | 
			
		||||
    clutter_stage_view_get_instance_private (view);
 | 
			
		||||
 | 
			
		||||
  return g_steal_pointer (&priv->next_scanout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_stage_view_get_property (GObject    *object,
 | 
			
		||||
                                 guint       prop_id,
 | 
			
		||||
 
 | 
			
		||||
@@ -62,16 +62,6 @@ _clutter_stage_window_set_title (ClutterStageWindow *window,
 | 
			
		||||
    iface->set_title (window, title);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_clutter_stage_window_set_cursor_visible (ClutterStageWindow *window,
 | 
			
		||||
                                          gboolean            is_visible)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageWindowInterface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
 | 
			
		||||
 | 
			
		||||
  if (iface->set_cursor_visible)
 | 
			
		||||
    iface->set_cursor_visible (window, is_visible);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
_clutter_stage_window_realize (ClutterStageWindow *window)
 | 
			
		||||
{
 | 
			
		||||
@@ -178,19 +168,6 @@ _clutter_stage_window_clear_update_time (ClutterStageWindow *window)
 | 
			
		||||
  iface->clear_update_time (window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_clutter_stage_window_set_accept_focus (ClutterStageWindow *window,
 | 
			
		||||
                                        gboolean            accept_focus)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageWindowInterface *iface;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window));
 | 
			
		||||
 | 
			
		||||
  iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
 | 
			
		||||
  if (iface->set_accept_focus)
 | 
			
		||||
    iface->set_accept_focus (window, accept_focus);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_clutter_stage_window_redraw (ClutterStageWindow *window)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -30,8 +30,6 @@ struct _ClutterStageWindowInterface
 | 
			
		||||
 | 
			
		||||
  void              (* set_title)               (ClutterStageWindow *stage_window,
 | 
			
		||||
                                                 const gchar        *title);
 | 
			
		||||
  void              (* set_cursor_visible)      (ClutterStageWindow *stage_window,
 | 
			
		||||
                                                 gboolean            cursor_visible);
 | 
			
		||||
 | 
			
		||||
  gboolean          (* realize)                 (ClutterStageWindow *stage_window);
 | 
			
		||||
  void              (* unrealize)               (ClutterStageWindow *stage_window);
 | 
			
		||||
@@ -51,9 +49,6 @@ struct _ClutterStageWindowInterface
 | 
			
		||||
  gint64            (* get_update_time)         (ClutterStageWindow *stage_window);
 | 
			
		||||
  void              (* clear_update_time)       (ClutterStageWindow *stage_window);
 | 
			
		||||
 | 
			
		||||
  void              (* set_accept_focus)        (ClutterStageWindow *stage_window,
 | 
			
		||||
                                                 gboolean            accept_focus);
 | 
			
		||||
 | 
			
		||||
  void              (* redraw)                  (ClutterStageWindow *stage_window);
 | 
			
		||||
 | 
			
		||||
  gboolean          (* can_clip_redraws)        (ClutterStageWindow *stage_window);
 | 
			
		||||
 
 | 
			
		||||
@@ -78,7 +78,6 @@
 | 
			
		||||
#include "clutter-private.h"
 | 
			
		||||
 | 
			
		||||
#include "cogl/cogl.h"
 | 
			
		||||
#include "cogl/cogl-trace.h"
 | 
			
		||||
 | 
			
		||||
struct _ClutterStageQueueRedrawEntry
 | 
			
		||||
{
 | 
			
		||||
@@ -141,19 +140,12 @@ struct _ClutterStagePrivate
 | 
			
		||||
 | 
			
		||||
  ClutterStageState current_state;
 | 
			
		||||
 | 
			
		||||
  gpointer paint_data;
 | 
			
		||||
  GDestroyNotify paint_notify;
 | 
			
		||||
 | 
			
		||||
  int update_freeze_count;
 | 
			
		||||
 | 
			
		||||
  guint redraw_pending         : 1;
 | 
			
		||||
  guint is_cursor_visible      : 1;
 | 
			
		||||
  guint throttle_motion_events : 1;
 | 
			
		||||
  guint use_alpha              : 1;
 | 
			
		||||
  guint min_size_changed       : 1;
 | 
			
		||||
  guint accept_focus           : 1;
 | 
			
		||||
  guint motion_events_enabled  : 1;
 | 
			
		||||
  guint has_custom_perspective : 1;
 | 
			
		||||
  guint stage_was_relayout     : 1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -162,12 +154,9 @@ enum
 | 
			
		||||
  PROP_0,
 | 
			
		||||
 | 
			
		||||
  PROP_COLOR,
 | 
			
		||||
  PROP_CURSOR_VISIBLE,
 | 
			
		||||
  PROP_PERSPECTIVE,
 | 
			
		||||
  PROP_TITLE,
 | 
			
		||||
  PROP_USE_ALPHA,
 | 
			
		||||
  PROP_KEY_FOCUS,
 | 
			
		||||
  PROP_ACCEPT_FOCUS,
 | 
			
		||||
  PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -563,7 +552,7 @@ clutter_stage_add_redraw_clip (ClutterStage          *stage,
 | 
			
		||||
{
 | 
			
		||||
  GList *l;
 | 
			
		||||
 | 
			
		||||
  for (l = _clutter_stage_peek_stage_views (stage); l; l = l->next)
 | 
			
		||||
  for (l = clutter_stage_peek_stage_views (stage); l; l = l->next)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterStageView *view = l->data;
 | 
			
		||||
 | 
			
		||||
@@ -935,7 +924,8 @@ clutter_stage_do_paint_view (ClutterStage         *stage,
 | 
			
		||||
  ClutterPaintContext *paint_context;
 | 
			
		||||
  cairo_rectangle_int_t clip_rect;
 | 
			
		||||
 | 
			
		||||
  paint_context = clutter_paint_context_new_for_view (view, redraw_clip);
 | 
			
		||||
  paint_context = clutter_paint_context_new_for_view (view, redraw_clip,
 | 
			
		||||
                                                      CLUTTER_PAINT_FLAG_NONE);
 | 
			
		||||
 | 
			
		||||
  cairo_region_get_extents (redraw_clip, &clip_rect);
 | 
			
		||||
  setup_view_for_pick_or_paint (stage, view, &clip_rect);
 | 
			
		||||
@@ -1321,15 +1311,9 @@ clutter_stage_queue_actor_relayout (ClutterStage *stage,
 | 
			
		||||
{
 | 
			
		||||
  ClutterStagePrivate *priv = stage->priv;
 | 
			
		||||
 | 
			
		||||
  if (g_hash_table_contains (priv->pending_relayouts, stage))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (g_hash_table_size (priv->pending_relayouts) == 0)
 | 
			
		||||
    _clutter_stage_schedule_update (stage);
 | 
			
		||||
 | 
			
		||||
  if (actor == (ClutterActor *) stage)
 | 
			
		||||
    g_hash_table_remove_all (priv->pending_relayouts);
 | 
			
		||||
 | 
			
		||||
  g_hash_table_add (priv->pending_relayouts, g_object_ref (actor));
 | 
			
		||||
  priv->pending_relayouts_version++;
 | 
			
		||||
}
 | 
			
		||||
@@ -1589,7 +1573,7 @@ is_full_stage_redraw_queued (ClutterStage *stage)
 | 
			
		||||
{
 | 
			
		||||
  GList *l;
 | 
			
		||||
 | 
			
		||||
  for (l = _clutter_stage_peek_stage_views (stage); l; l = l->next)
 | 
			
		||||
  for (l = clutter_stage_peek_stage_views (stage); l; l = l->next)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterStageView *view = l->data;
 | 
			
		||||
 | 
			
		||||
@@ -1853,33 +1837,14 @@ clutter_stage_set_property (GObject      *object,
 | 
			
		||||
                                          clutter_value_get_color (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_CURSOR_VISIBLE:
 | 
			
		||||
      if (g_value_get_boolean (value))
 | 
			
		||||
        clutter_stage_show_cursor (stage);
 | 
			
		||||
      else
 | 
			
		||||
        clutter_stage_hide_cursor (stage);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_PERSPECTIVE:
 | 
			
		||||
      clutter_stage_set_perspective (stage, g_value_get_boxed (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_TITLE:
 | 
			
		||||
      clutter_stage_set_title (stage, g_value_get_string (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_USE_ALPHA:
 | 
			
		||||
      clutter_stage_set_use_alpha (stage, g_value_get_boolean (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_KEY_FOCUS:
 | 
			
		||||
      clutter_stage_set_key_focus (stage, g_value_get_object (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_ACCEPT_FOCUS:
 | 
			
		||||
      clutter_stage_set_accept_focus (stage, g_value_get_boolean (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
@@ -1906,10 +1871,6 @@ clutter_stage_get_property (GObject    *gobject,
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_CURSOR_VISIBLE:
 | 
			
		||||
      g_value_set_boolean (value, priv->is_cursor_visible);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_PERSPECTIVE:
 | 
			
		||||
      g_value_set_boxed (value, &priv->perspective);
 | 
			
		||||
      break;
 | 
			
		||||
@@ -1918,18 +1879,10 @@ clutter_stage_get_property (GObject    *gobject,
 | 
			
		||||
      g_value_set_string (value, priv->title);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_USE_ALPHA:
 | 
			
		||||
      g_value_set_boolean (value, priv->use_alpha);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_KEY_FOCUS:
 | 
			
		||||
      g_value_set_object (value, priv->key_focused_actor);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_ACCEPT_FOCUS:
 | 
			
		||||
      g_value_set_boolean (value, priv->accept_focus);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
@@ -1993,9 +1946,6 @@ clutter_stage_finalize (GObject *object)
 | 
			
		||||
  if (priv->fps_timer != NULL)
 | 
			
		||||
    g_timer_destroy (priv->fps_timer);
 | 
			
		||||
 | 
			
		||||
  if (priv->paint_notify != NULL)
 | 
			
		||||
    priv->paint_notify (priv->paint_data);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (clutter_stage_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -2037,18 +1987,6 @@ clutter_stage_class_init (ClutterStageClass *klass)
 | 
			
		||||
 | 
			
		||||
  klass->paint_view = clutter_stage_real_paint_view;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ClutterStage:cursor-visible:
 | 
			
		||||
   *
 | 
			
		||||
   * Whether the mouse pointer should be visible
 | 
			
		||||
   */
 | 
			
		||||
  obj_props[PROP_CURSOR_VISIBLE] =
 | 
			
		||||
      g_param_spec_boolean ("cursor-visible",
 | 
			
		||||
                            P_("Cursor Visible"),
 | 
			
		||||
                            P_("Whether the mouse pointer is visible on the main stage"),
 | 
			
		||||
                            TRUE,
 | 
			
		||||
                            CLUTTER_PARAM_READWRITE);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ClutterStage:color:
 | 
			
		||||
   *
 | 
			
		||||
@@ -2078,7 +2016,7 @@ clutter_stage_class_init (ClutterStageClass *klass)
 | 
			
		||||
                          P_("Perspective"),
 | 
			
		||||
                          P_("Perspective projection parameters"),
 | 
			
		||||
                          CLUTTER_TYPE_PERSPECTIVE,
 | 
			
		||||
                          CLUTTER_PARAM_READWRITE);
 | 
			
		||||
                          CLUTTER_PARAM_READABLE);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ClutterStage:title:
 | 
			
		||||
@@ -2094,23 +2032,6 @@ clutter_stage_class_init (ClutterStageClass *klass)
 | 
			
		||||
                           NULL,
 | 
			
		||||
                           CLUTTER_PARAM_READWRITE);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ClutterStage:use-alpha:
 | 
			
		||||
   *
 | 
			
		||||
   * Whether the #ClutterStage should honour the alpha component of the
 | 
			
		||||
   * #ClutterStage:color property when painting. If Clutter is run under
 | 
			
		||||
   * a compositing manager this will result in the stage being blended
 | 
			
		||||
   * with the underlying window(s)
 | 
			
		||||
   *
 | 
			
		||||
   * Since: 1.2
 | 
			
		||||
   */
 | 
			
		||||
  obj_props[PROP_USE_ALPHA] =
 | 
			
		||||
      g_param_spec_boolean ("use-alpha",
 | 
			
		||||
                            P_("Use Alpha"),
 | 
			
		||||
                            P_("Whether to honour the alpha component of the stage color"),
 | 
			
		||||
                            FALSE,
 | 
			
		||||
                            CLUTTER_PARAM_READWRITE);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ClutterStage:key-focus:
 | 
			
		||||
   *
 | 
			
		||||
@@ -2128,20 +2049,6 @@ clutter_stage_class_init (ClutterStageClass *klass)
 | 
			
		||||
                           CLUTTER_TYPE_ACTOR,
 | 
			
		||||
                           CLUTTER_PARAM_READWRITE);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ClutterStage:accept-focus:
 | 
			
		||||
   *
 | 
			
		||||
   * Whether the #ClutterStage should accept key focus when shown.
 | 
			
		||||
   *
 | 
			
		||||
   * Since: 1.6
 | 
			
		||||
   */
 | 
			
		||||
  obj_props[PROP_ACCEPT_FOCUS] =
 | 
			
		||||
      g_param_spec_boolean ("accept-focus",
 | 
			
		||||
                            P_("Accept Focus"),
 | 
			
		||||
                            P_("Whether the stage should accept focus on show"),
 | 
			
		||||
                            TRUE,
 | 
			
		||||
                            CLUTTER_PARAM_READWRITE);
 | 
			
		||||
 | 
			
		||||
  g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
@@ -2316,7 +2223,6 @@ clutter_stage_init (ClutterStage *self)
 | 
			
		||||
 | 
			
		||||
  priv->event_queue = g_queue_new ();
 | 
			
		||||
 | 
			
		||||
  priv->is_cursor_visible = TRUE;
 | 
			
		||||
  priv->throttle_motion_events = TRUE;
 | 
			
		||||
  priv->min_size_changed = FALSE;
 | 
			
		||||
  priv->sync_delay = -1;
 | 
			
		||||
@@ -2439,8 +2345,8 @@ clutter_stage_get_color (ClutterStage *stage,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_stage_set_perspective_internal (ClutterStage       *stage,
 | 
			
		||||
                                        ClutterPerspective *perspective)
 | 
			
		||||
clutter_stage_set_perspective (ClutterStage       *stage,
 | 
			
		||||
                               ClutterPerspective *perspective)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStagePrivate *priv = stage->priv;
 | 
			
		||||
 | 
			
		||||
@@ -2465,36 +2371,6 @@ clutter_stage_set_perspective_internal (ClutterStage       *stage,
 | 
			
		||||
  clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_stage_set_perspective:
 | 
			
		||||
 * @stage: A #ClutterStage
 | 
			
		||||
 * @perspective: A #ClutterPerspective
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the stage perspective. Using this function is not recommended
 | 
			
		||||
 * because it will disable Clutter's attempts to generate an
 | 
			
		||||
 * appropriate perspective based on the size of the stage.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
clutter_stage_set_perspective (ClutterStage       *stage,
 | 
			
		||||
                               ClutterPerspective *perspective)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStagePrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_STAGE (stage));
 | 
			
		||||
  g_return_if_fail (perspective != NULL);
 | 
			
		||||
  g_return_if_fail (perspective->z_far - perspective->z_near != 0);
 | 
			
		||||
 | 
			
		||||
  priv = stage->priv;
 | 
			
		||||
 | 
			
		||||
  /* If the application ever calls this function then we'll stop
 | 
			
		||||
     automatically updating the perspective when the stage changes
 | 
			
		||||
     size */
 | 
			
		||||
  priv->has_custom_perspective = TRUE;
 | 
			
		||||
 | 
			
		||||
  clutter_stage_set_perspective_internal (stage, perspective);
 | 
			
		||||
  clutter_stage_update_view_perspective (stage);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_stage_get_perspective:
 | 
			
		||||
 * @stage: A #ClutterStage
 | 
			
		||||
@@ -2521,7 +2397,7 @@ clutter_stage_get_perspective (ClutterStage       *stage,
 | 
			
		||||
 *              @stage.
 | 
			
		||||
 *
 | 
			
		||||
 * Retrieves the @stage's projection matrix. This is derived from the
 | 
			
		||||
 * current perspective set using clutter_stage_set_perspective().
 | 
			
		||||
 * current perspective.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.6
 | 
			
		||||
 */
 | 
			
		||||
@@ -2685,72 +2561,6 @@ _clutter_stage_get_viewport (ClutterStage *stage,
 | 
			
		||||
  *height = priv->viewport[3];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_stage_show_cursor:
 | 
			
		||||
 * @stage: a #ClutterStage
 | 
			
		||||
 *
 | 
			
		||||
 * Shows the cursor on the stage window
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
clutter_stage_show_cursor (ClutterStage *stage)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStagePrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_STAGE (stage));
 | 
			
		||||
 | 
			
		||||
  priv = stage->priv;
 | 
			
		||||
  if (!priv->is_cursor_visible)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterStageWindow *impl = CLUTTER_STAGE_WINDOW (priv->impl);
 | 
			
		||||
      ClutterStageWindowInterface *iface;
 | 
			
		||||
 | 
			
		||||
      iface = CLUTTER_STAGE_WINDOW_GET_IFACE (impl);
 | 
			
		||||
      if (iface->set_cursor_visible)
 | 
			
		||||
        {
 | 
			
		||||
          priv->is_cursor_visible = TRUE;
 | 
			
		||||
 | 
			
		||||
          iface->set_cursor_visible (impl, TRUE);
 | 
			
		||||
 | 
			
		||||
          g_object_notify_by_pspec (G_OBJECT (stage),
 | 
			
		||||
                                    obj_props[PROP_CURSOR_VISIBLE]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_stage_hide_cursor:
 | 
			
		||||
 * @stage: a #ClutterStage
 | 
			
		||||
 *
 | 
			
		||||
 * Makes the cursor invisible on the stage window
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 0.4
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
clutter_stage_hide_cursor (ClutterStage *stage)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStagePrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_STAGE (stage));
 | 
			
		||||
 | 
			
		||||
  priv = stage->priv;
 | 
			
		||||
  if (priv->is_cursor_visible)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterStageWindow *impl = CLUTTER_STAGE_WINDOW (priv->impl);
 | 
			
		||||
      ClutterStageWindowInterface *iface;
 | 
			
		||||
 | 
			
		||||
      iface = CLUTTER_STAGE_WINDOW_GET_IFACE (impl);
 | 
			
		||||
      if (iface->set_cursor_visible)
 | 
			
		||||
        {
 | 
			
		||||
          priv->is_cursor_visible = FALSE;
 | 
			
		||||
 | 
			
		||||
          iface->set_cursor_visible (impl, FALSE);
 | 
			
		||||
 | 
			
		||||
          g_object_notify_by_pspec (G_OBJECT (stage),
 | 
			
		||||
                                    obj_props[PROP_CURSOR_VISIBLE]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_stage_read_pixels:
 | 
			
		||||
 * @stage: A #ClutterStage
 | 
			
		||||
@@ -3302,30 +3112,20 @@ clutter_stage_update_view_perspective (ClutterStage *stage)
 | 
			
		||||
 | 
			
		||||
  perspective = priv->perspective;
 | 
			
		||||
 | 
			
		||||
  /* Ideally we want to regenerate the perspective matrix whenever
 | 
			
		||||
   * the size changes but if the user has provided a custom matrix
 | 
			
		||||
   * then we don't want to override it */
 | 
			
		||||
  if (!priv->has_custom_perspective)
 | 
			
		||||
    {
 | 
			
		||||
      perspective.fovy = 60.0; /* 60 Degrees */
 | 
			
		||||
      perspective.z_near = 0.1;
 | 
			
		||||
      perspective.aspect = priv->viewport[2] / priv->viewport[3];
 | 
			
		||||
      z_2d = calculate_z_translation (perspective.z_near);
 | 
			
		||||
  perspective.fovy = 60.0; /* 60 Degrees */
 | 
			
		||||
  perspective.z_near = 0.1;
 | 
			
		||||
  perspective.aspect = priv->viewport[2] / priv->viewport[3];
 | 
			
		||||
  z_2d = calculate_z_translation (perspective.z_near);
 | 
			
		||||
 | 
			
		||||
      /* NB: z_2d is only enough room for 85% of the stage_height between
 | 
			
		||||
       * the stage and the z_near plane. For behind the stage plane we
 | 
			
		||||
       * want a more consistent gap of 10 times the stage_height before
 | 
			
		||||
       * hitting the far plane so we calculate that relative to the final
 | 
			
		||||
       * height of the stage plane at the z_2d_distance we got... */
 | 
			
		||||
      perspective.z_far = z_2d +
 | 
			
		||||
        tanf (_DEG_TO_RAD (perspective.fovy / 2.0f)) * z_2d * 20.0f;
 | 
			
		||||
  /* NB: z_2d is only enough room for 85% of the stage_height between
 | 
			
		||||
   * the stage and the z_near plane. For behind the stage plane we
 | 
			
		||||
   * want a more consistent gap of 10 times the stage_height before
 | 
			
		||||
   * hitting the far plane so we calculate that relative to the final
 | 
			
		||||
   * height of the stage plane at the z_2d_distance we got... */
 | 
			
		||||
  perspective.z_far = z_2d +
 | 
			
		||||
    tanf (_DEG_TO_RAD (perspective.fovy / 2.0f)) * z_2d * 20.0f;
 | 
			
		||||
 | 
			
		||||
      clutter_stage_set_perspective_internal (stage, &perspective);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      z_2d = calculate_z_translation (perspective.z_near);
 | 
			
		||||
    }
 | 
			
		||||
  clutter_stage_set_perspective (stage, &perspective);
 | 
			
		||||
 | 
			
		||||
  cogl_matrix_init_identity (&priv->view);
 | 
			
		||||
  cogl_matrix_view_2d_in_perspective (&priv->view,
 | 
			
		||||
@@ -3555,56 +3355,6 @@ clutter_stage_get_throttle_motion_events (ClutterStage *stage)
 | 
			
		||||
  return stage->priv->throttle_motion_events;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_stage_set_use_alpha:
 | 
			
		||||
 * @stage: a #ClutterStage
 | 
			
		||||
 * @use_alpha: whether the stage should honour the opacity or the
 | 
			
		||||
 *   alpha channel of the stage color
 | 
			
		||||
 *
 | 
			
		||||
 * Sets whether the @stage should honour the #ClutterActor:opacity and
 | 
			
		||||
 * the alpha channel of the #ClutterStage:color
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.2
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
clutter_stage_set_use_alpha (ClutterStage *stage,
 | 
			
		||||
                             gboolean      use_alpha)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStagePrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_STAGE (stage));
 | 
			
		||||
 | 
			
		||||
  priv = stage->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->use_alpha != use_alpha)
 | 
			
		||||
    {
 | 
			
		||||
      priv->use_alpha = use_alpha;
 | 
			
		||||
 | 
			
		||||
      clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
 | 
			
		||||
 | 
			
		||||
      g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_USE_ALPHA]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_stage_get_use_alpha:
 | 
			
		||||
 * @stage: a #ClutterStage
 | 
			
		||||
 *
 | 
			
		||||
 * Retrieves the value set using clutter_stage_set_use_alpha()
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: %TRUE if the stage should honour the opacity and the
 | 
			
		||||
 *   alpha channel of the stage color
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.2
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
clutter_stage_get_use_alpha (ClutterStage *stage)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE);
 | 
			
		||||
 | 
			
		||||
  return stage->priv->use_alpha;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_stage_set_minimum_size:
 | 
			
		||||
 * @stage: a #ClutterStage
 | 
			
		||||
@@ -3951,56 +3701,6 @@ clutter_stage_maybe_finish_queue_redraws (ClutterStage *stage)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_stage_set_accept_focus:
 | 
			
		||||
 * @stage: a #ClutterStage
 | 
			
		||||
 * @accept_focus: %TRUE to accept focus on show
 | 
			
		||||
 *
 | 
			
		||||
 * Sets whether the @stage should accept the key focus when shown.
 | 
			
		||||
 *
 | 
			
		||||
 * This function should be called before showing @stage using
 | 
			
		||||
 * clutter_actor_show().
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.6
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
clutter_stage_set_accept_focus (ClutterStage *stage,
 | 
			
		||||
                                gboolean      accept_focus)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStagePrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_STAGE (stage));
 | 
			
		||||
 | 
			
		||||
  accept_focus = !!accept_focus;
 | 
			
		||||
 | 
			
		||||
  priv = stage->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->accept_focus != accept_focus)
 | 
			
		||||
    {
 | 
			
		||||
      _clutter_stage_window_set_accept_focus (priv->impl, accept_focus);
 | 
			
		||||
      g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_ACCEPT_FOCUS]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_stage_get_accept_focus:
 | 
			
		||||
 * @stage: a #ClutterStage
 | 
			
		||||
 *
 | 
			
		||||
 * Retrieves the value set with clutter_stage_set_accept_focus().
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: %TRUE if the #ClutterStage should accept focus, and %FALSE
 | 
			
		||||
 *   otherwise
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.6
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
clutter_stage_get_accept_focus (ClutterStage *stage)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_STAGE (stage), TRUE);
 | 
			
		||||
 | 
			
		||||
  return stage->priv->accept_focus;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_stage_set_motion_events_enabled:
 | 
			
		||||
 * @stage: a #ClutterStage
 | 
			
		||||
@@ -4349,6 +4049,20 @@ capture_view (ClutterStage          *stage,
 | 
			
		||||
  cairo_surface_mark_dirty (capture->image);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_stage_capture:
 | 
			
		||||
 * @stage: a #ClutterStage
 | 
			
		||||
 * @paint: whether to pain the frame
 | 
			
		||||
 * @rect: a #cairo_rectangle_int_t in stage coordinates
 | 
			
		||||
 * @out_captures: (out) (array length=out_n_captures): an array of
 | 
			
		||||
 *   #ClutterCapture
 | 
			
		||||
 * @out_n_captures: (out): the number of captures in @out_captures
 | 
			
		||||
 *
 | 
			
		||||
 * Captures the stage pixels of @rect into @captures. @rect is in stage
 | 
			
		||||
 * coordinates.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE if a #ClutterCapture has been created, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
clutter_stage_capture (ClutterStage          *stage,
 | 
			
		||||
                       gboolean               paint,
 | 
			
		||||
@@ -4450,6 +4164,97 @@ clutter_stage_get_capture_final_size (ClutterStage          *stage,
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_stage_paint_to_framebuffer (ClutterStage                *stage,
 | 
			
		||||
                                    CoglFramebuffer             *framebuffer,
 | 
			
		||||
                                    const cairo_rectangle_int_t *rect,
 | 
			
		||||
                                    float                        scale,
 | 
			
		||||
                                    ClutterPaintFlag             paint_flags)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStagePrivate *priv = stage->priv;
 | 
			
		||||
  ClutterPaintContext *paint_context;
 | 
			
		||||
  cairo_region_t *redraw_clip;
 | 
			
		||||
 | 
			
		||||
  redraw_clip = cairo_region_create_rectangle (rect);
 | 
			
		||||
  paint_context =
 | 
			
		||||
    clutter_paint_context_new_for_framebuffer (framebuffer,
 | 
			
		||||
                                               redraw_clip,
 | 
			
		||||
                                               paint_flags);
 | 
			
		||||
  cairo_region_destroy (redraw_clip);
 | 
			
		||||
 | 
			
		||||
  cogl_framebuffer_push_matrix (framebuffer);
 | 
			
		||||
  cogl_framebuffer_set_projection_matrix (framebuffer, &priv->projection);
 | 
			
		||||
  cogl_framebuffer_set_viewport (framebuffer,
 | 
			
		||||
                                 -(rect->x * scale),
 | 
			
		||||
                                 -(rect->y * scale),
 | 
			
		||||
                                 priv->viewport[2] * scale,
 | 
			
		||||
                                 priv->viewport[3] * scale);
 | 
			
		||||
  clutter_actor_paint (CLUTTER_ACTOR (stage), paint_context);
 | 
			
		||||
  cogl_framebuffer_pop_matrix (framebuffer);
 | 
			
		||||
 | 
			
		||||
  clutter_paint_context_destroy (paint_context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
clutter_stage_paint_to_buffer (ClutterStage                 *stage,
 | 
			
		||||
                               const cairo_rectangle_int_t  *rect,
 | 
			
		||||
                               float                         scale,
 | 
			
		||||
                               uint8_t                      *data,
 | 
			
		||||
                               int                           stride,
 | 
			
		||||
                               CoglPixelFormat               format,
 | 
			
		||||
                               ClutterPaintFlag              paint_flags,
 | 
			
		||||
                               GError                      **error)
 | 
			
		||||
{
 | 
			
		||||
  ClutterBackend *clutter_backend = clutter_get_default_backend ();
 | 
			
		||||
  CoglContext *cogl_context =
 | 
			
		||||
    clutter_backend_get_cogl_context (clutter_backend);
 | 
			
		||||
  int texture_width, texture_height;
 | 
			
		||||
  CoglTexture2D *texture;
 | 
			
		||||
  CoglOffscreen *offscreen;
 | 
			
		||||
  CoglFramebuffer *framebuffer;
 | 
			
		||||
  CoglBitmap *bitmap;
 | 
			
		||||
 | 
			
		||||
  texture_width = (int) ceilf (rect->width * scale);
 | 
			
		||||
  texture_height = (int) ceilf (rect->height * scale);
 | 
			
		||||
  texture = cogl_texture_2d_new_with_size (cogl_context,
 | 
			
		||||
                                           texture_width,
 | 
			
		||||
                                           texture_height);
 | 
			
		||||
  if (!texture)
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
 | 
			
		||||
                   "Failed to create %dx%d texture",
 | 
			
		||||
                   texture_width, texture_height);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture));
 | 
			
		||||
  framebuffer = COGL_FRAMEBUFFER (offscreen);
 | 
			
		||||
 | 
			
		||||
  cogl_object_unref (texture);
 | 
			
		||||
 | 
			
		||||
  if (!cogl_framebuffer_allocate (framebuffer, error))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  clutter_stage_paint_to_framebuffer (stage, framebuffer,
 | 
			
		||||
                                      rect, scale, paint_flags);
 | 
			
		||||
 | 
			
		||||
  bitmap = cogl_bitmap_new_for_data (cogl_context,
 | 
			
		||||
                                     texture_width, texture_height,
 | 
			
		||||
                                     format,
 | 
			
		||||
                                     stride,
 | 
			
		||||
                                     data);
 | 
			
		||||
 | 
			
		||||
  cogl_framebuffer_read_pixels_into_bitmap (framebuffer,
 | 
			
		||||
                                            0, 0,
 | 
			
		||||
                                            COGL_READ_PIXELS_COLOR_BUFFER,
 | 
			
		||||
                                            bitmap);
 | 
			
		||||
 | 
			
		||||
  cogl_object_unref (bitmap);
 | 
			
		||||
  cogl_object_unref (framebuffer);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
capture_view_into (ClutterStage          *stage,
 | 
			
		||||
                   gboolean               paint,
 | 
			
		||||
@@ -4597,8 +4402,11 @@ clutter_stage_thaw_updates (ClutterStage *stage)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_stage_peek_stage_views: (skip)
 | 
			
		||||
 */
 | 
			
		||||
GList *
 | 
			
		||||
_clutter_stage_peek_stage_views (ClutterStage *stage)
 | 
			
		||||
clutter_stage_peek_stage_views (ClutterStage *stage)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStagePrivate *priv = stage->priv;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -103,8 +103,7 @@ struct _ClutterStageClass
 | 
			
		||||
 * @z_far: the distance from the viewer to the far clipping
 | 
			
		||||
 *   plane (always positive)
 | 
			
		||||
 *
 | 
			
		||||
 * Stage perspective definition. #ClutterPerspective is only used by
 | 
			
		||||
 * the fixed point version of clutter_stage_set_perspective().
 | 
			
		||||
 * Stage perspective definition.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 0.4
 | 
			
		||||
 */
 | 
			
		||||
@@ -140,17 +139,10 @@ GType clutter_stage_get_type (void) G_GNUC_CONST;
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
ClutterActor *  clutter_stage_new                               (void);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void            clutter_stage_set_perspective                   (ClutterStage          *stage,
 | 
			
		||||
			                                         ClutterPerspective    *perspective);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void            clutter_stage_get_perspective                   (ClutterStage          *stage,
 | 
			
		||||
			                                         ClutterPerspective    *perspective);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void            clutter_stage_show_cursor                       (ClutterStage          *stage);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void            clutter_stage_hide_cursor                       (ClutterStage          *stage);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void            clutter_stage_set_title                         (ClutterStage          *stage,
 | 
			
		||||
                                                                 const gchar           *title);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
@@ -186,11 +178,6 @@ void            clutter_stage_set_motion_events_enabled         (ClutterStage
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
gboolean        clutter_stage_get_motion_events_enabled         (ClutterStage          *stage);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void            clutter_stage_set_accept_focus                  (ClutterStage          *stage,
 | 
			
		||||
                                                                 gboolean               accept_focus);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
gboolean        clutter_stage_get_accept_focus                  (ClutterStage          *stage);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
gboolean        clutter_stage_event                             (ClutterStage          *stage,
 | 
			
		||||
                                                                 ClutterEvent          *event);
 | 
			
		||||
 | 
			
		||||
@@ -233,8 +220,8 @@ CLUTTER_EXPORT
 | 
			
		||||
gboolean clutter_stage_capture (ClutterStage          *stage,
 | 
			
		||||
                                gboolean               paint,
 | 
			
		||||
                                cairo_rectangle_int_t *rect,
 | 
			
		||||
                                ClutterCapture       **captures,
 | 
			
		||||
                                int                   *n_captures);
 | 
			
		||||
                                ClutterCapture       **out_captures,
 | 
			
		||||
                                int                   *out_n_captures);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
ClutterStageView * clutter_stage_get_view_at (ClutterStage *stage,
 | 
			
		||||
                                              float         x,
 | 
			
		||||
 
 | 
			
		||||
@@ -348,13 +348,23 @@ clutter_text_input_focus_request_surrounding (ClutterInputFocus *focus)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_text_input_focus_delete_surrounding (ClutterInputFocus *focus,
 | 
			
		||||
                                             guint              offset,
 | 
			
		||||
                                             int                offset,
 | 
			
		||||
                                             guint              len)
 | 
			
		||||
{
 | 
			
		||||
  ClutterText *clutter_text = CLUTTER_TEXT_INPUT_FOCUS (focus)->text;
 | 
			
		||||
  int cursor;
 | 
			
		||||
  int start;
 | 
			
		||||
 | 
			
		||||
  cursor = clutter_text_get_cursor_position (clutter_text);
 | 
			
		||||
  start = cursor + offset;
 | 
			
		||||
  if (start < 0)
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("The offset '%d' of deleting surrounding is larger than the cursor pos '%d'",
 | 
			
		||||
                 offset, cursor);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  if (clutter_text_get_editable (clutter_text))
 | 
			
		||||
    clutter_text_delete_text (clutter_text, offset, len);
 | 
			
		||||
    clutter_text_delete_text (clutter_text, start, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -1897,14 +1907,6 @@ clutter_text_foreach_selection_rectangle (ClutterText              *self,
 | 
			
		||||
  g_free (utf8);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
add_selection_rectangle_to_path (ClutterText           *text,
 | 
			
		||||
                                 const ClutterActorBox *box,
 | 
			
		||||
                                 gpointer               user_data)
 | 
			
		||||
{
 | 
			
		||||
  cogl_path_rectangle (user_data, box->x1, box->y1, box->x2, box->y2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_text_foreach_selection_rectangle_prescaled (ClutterText              *self,
 | 
			
		||||
                                                    ClutterTextSelectionFunc  func,
 | 
			
		||||
@@ -1913,6 +1915,60 @@ clutter_text_foreach_selection_rectangle_prescaled (ClutterText              *se
 | 
			
		||||
  clutter_text_foreach_selection_rectangle (self, 1.0f, func, user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
paint_selection_rectangle (ClutterText           *self,
 | 
			
		||||
                           const ClutterActorBox *box,
 | 
			
		||||
                           gpointer               user_data)
 | 
			
		||||
{
 | 
			
		||||
  CoglFramebuffer *fb = user_data;
 | 
			
		||||
  ClutterTextPrivate *priv = self->priv;
 | 
			
		||||
  ClutterActor *actor = CLUTTER_ACTOR (self);
 | 
			
		||||
  guint8 paint_opacity = clutter_actor_get_paint_opacity (actor);
 | 
			
		||||
  CoglPipeline *color_pipeline = cogl_pipeline_copy (default_color_pipeline);
 | 
			
		||||
  PangoLayout *layout = clutter_text_get_layout (self);
 | 
			
		||||
  CoglColor cogl_color = { 0, };
 | 
			
		||||
  const ClutterColor *color;
 | 
			
		||||
 | 
			
		||||
  /* Paint selection background */
 | 
			
		||||
  if (priv->selection_color_set)
 | 
			
		||||
    color = &priv->selection_color;
 | 
			
		||||
  else if (priv->cursor_color_set)
 | 
			
		||||
    color = &priv->cursor_color;
 | 
			
		||||
  else
 | 
			
		||||
    color = &priv->text_color;
 | 
			
		||||
 | 
			
		||||
  cogl_color_init_from_4ub (&cogl_color,
 | 
			
		||||
                            color->red,
 | 
			
		||||
                            color->green,
 | 
			
		||||
                            color->blue,
 | 
			
		||||
                            paint_opacity * color->alpha / 255);
 | 
			
		||||
  cogl_color_premultiply (&cogl_color);
 | 
			
		||||
  cogl_pipeline_set_color (color_pipeline, &cogl_color);
 | 
			
		||||
 | 
			
		||||
  cogl_framebuffer_push_rectangle_clip (fb,
 | 
			
		||||
                                        box->x1, box->y1,
 | 
			
		||||
                                        box->x2, box->y2);
 | 
			
		||||
  cogl_framebuffer_draw_rectangle (fb, color_pipeline,
 | 
			
		||||
                                   box->x1, box->y1,
 | 
			
		||||
                                   box->x2, box->y2);
 | 
			
		||||
 | 
			
		||||
  if (priv->selected_text_color_set)
 | 
			
		||||
    color = &priv->selected_text_color;
 | 
			
		||||
  else
 | 
			
		||||
    color = &priv->text_color;
 | 
			
		||||
 | 
			
		||||
  cogl_color_init_from_4ub (&cogl_color,
 | 
			
		||||
                            color->red,
 | 
			
		||||
                            color->green,
 | 
			
		||||
                            color->blue,
 | 
			
		||||
                            paint_opacity * color->alpha / 255);
 | 
			
		||||
 | 
			
		||||
  cogl_pango_show_layout (fb, layout, priv->text_x, 0, &cogl_color);
 | 
			
		||||
 | 
			
		||||
  cogl_framebuffer_pop_clip (fb);
 | 
			
		||||
  cogl_object_unref (color_pipeline);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Draws the selected text, its background, and the cursor */
 | 
			
		||||
static void
 | 
			
		||||
selection_paint (ClutterText     *self,
 | 
			
		||||
@@ -1955,52 +2011,9 @@ selection_paint (ClutterText     *self,
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      /* Paint selection background first */
 | 
			
		||||
      CoglPipeline *color_pipeline = cogl_pipeline_copy (default_color_pipeline);
 | 
			
		||||
      PangoLayout *layout = clutter_text_get_layout (self);
 | 
			
		||||
      CoglPath *selection_path = cogl_path_new ();
 | 
			
		||||
      CoglColor cogl_color = { 0, };
 | 
			
		||||
 | 
			
		||||
      /* Paint selection background */
 | 
			
		||||
      if (priv->selection_color_set)
 | 
			
		||||
        color = &priv->selection_color;
 | 
			
		||||
      else if (priv->cursor_color_set)
 | 
			
		||||
        color = &priv->cursor_color;
 | 
			
		||||
      else
 | 
			
		||||
        color = &priv->text_color;
 | 
			
		||||
 | 
			
		||||
      cogl_color_init_from_4ub (&cogl_color,
 | 
			
		||||
                                color->red,
 | 
			
		||||
                                color->green,
 | 
			
		||||
                                color->blue,
 | 
			
		||||
                                paint_opacity * color->alpha / 255);
 | 
			
		||||
      cogl_color_premultiply (&cogl_color);
 | 
			
		||||
      cogl_pipeline_set_color (color_pipeline, &cogl_color);
 | 
			
		||||
 | 
			
		||||
      clutter_text_foreach_selection_rectangle_prescaled (self,
 | 
			
		||||
                                                          add_selection_rectangle_to_path,
 | 
			
		||||
                                                          selection_path);
 | 
			
		||||
 | 
			
		||||
      cogl_framebuffer_fill_path (fb, color_pipeline, selection_path);
 | 
			
		||||
 | 
			
		||||
      /* Paint selected text */
 | 
			
		||||
      cogl_framebuffer_push_path_clip (fb, selection_path);
 | 
			
		||||
      cogl_object_unref (selection_path);
 | 
			
		||||
 | 
			
		||||
      if (priv->selected_text_color_set)
 | 
			
		||||
        color = &priv->selected_text_color;
 | 
			
		||||
      else
 | 
			
		||||
        color = &priv->text_color;
 | 
			
		||||
 | 
			
		||||
      cogl_color_init_from_4ub (&cogl_color,
 | 
			
		||||
                                color->red,
 | 
			
		||||
                                color->green,
 | 
			
		||||
                                color->blue,
 | 
			
		||||
                                paint_opacity * color->alpha / 255);
 | 
			
		||||
 | 
			
		||||
      cogl_pango_show_layout (fb, layout, priv->text_x, 0, &cogl_color);
 | 
			
		||||
 | 
			
		||||
      cogl_framebuffer_pop_clip (fb);
 | 
			
		||||
                                                          paint_selection_rectangle,
 | 
			
		||||
                                                          fb);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -56,8 +56,6 @@
 | 
			
		||||
#include "clutter-content.h"
 | 
			
		||||
#include "clutter-deform-effect.h"
 | 
			
		||||
#include "clutter-desaturate-effect.h"
 | 
			
		||||
#include "clutter-drag-action.h"
 | 
			
		||||
#include "clutter-drop-action.h"
 | 
			
		||||
#include "clutter-effect.h"
 | 
			
		||||
#include "clutter-enums.h"
 | 
			
		||||
#include "clutter-enum-types.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -47,8 +47,6 @@
 | 
			
		||||
#include "clutter-stage-private.h"
 | 
			
		||||
#include "clutter-stage-view-private.h"
 | 
			
		||||
 | 
			
		||||
#include "cogl/cogl-trace.h"
 | 
			
		||||
 | 
			
		||||
#define MAX_STACK_RECTS 256
 | 
			
		||||
 | 
			
		||||
typedef struct _ClutterStageViewCoglPrivate
 | 
			
		||||
@@ -377,15 +375,11 @@ static gboolean
 | 
			
		||||
swap_framebuffer (ClutterStageWindow *stage_window,
 | 
			
		||||
                  ClutterStageView   *view,
 | 
			
		||||
                  cairo_region_t     *swap_region,
 | 
			
		||||
                  gboolean            swap_with_damage,
 | 
			
		||||
                  cairo_region_t     *queued_redraw_clip)
 | 
			
		||||
                  gboolean            swap_with_damage)
 | 
			
		||||
{
 | 
			
		||||
  CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view);
 | 
			
		||||
  int *damage, n_rects, i;
 | 
			
		||||
 | 
			
		||||
  if (G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION)))
 | 
			
		||||
    paint_damage_region (stage_window, view, swap_region, queued_redraw_clip);
 | 
			
		||||
 | 
			
		||||
  n_rects = cairo_region_num_rectangles (swap_region);
 | 
			
		||||
  damage = g_newa (int, n_rects * 4);
 | 
			
		||||
  for (i = 0; i < n_rects; i++)
 | 
			
		||||
@@ -622,7 +616,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
 | 
			
		||||
  gboolean swap_with_damage;
 | 
			
		||||
  ClutterActor *wrapper;
 | 
			
		||||
  cairo_region_t *redraw_clip;
 | 
			
		||||
  cairo_region_t *queued_redraw_clip;
 | 
			
		||||
  cairo_region_t *queued_redraw_clip = NULL;
 | 
			
		||||
  cairo_region_t *fb_clip_region;
 | 
			
		||||
  cairo_region_t *swap_region;
 | 
			
		||||
  cairo_rectangle_int_t redraw_rect;
 | 
			
		||||
@@ -630,6 +624,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
 | 
			
		||||
  float fb_scale;
 | 
			
		||||
  int subpixel_compensation = 0;
 | 
			
		||||
  int fb_width, fb_height;
 | 
			
		||||
  int buffer_age;
 | 
			
		||||
 | 
			
		||||
  wrapper = CLUTTER_ACTOR (stage_cogl->wrapper);
 | 
			
		||||
 | 
			
		||||
@@ -645,6 +640,8 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
 | 
			
		||||
  has_buffer_age = cogl_is_onscreen (fb) && is_buffer_age_enabled ();
 | 
			
		||||
 | 
			
		||||
  redraw_clip = clutter_stage_view_take_redraw_clip (view);
 | 
			
		||||
  if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION))
 | 
			
		||||
    queued_redraw_clip = cairo_region_copy (redraw_clip);
 | 
			
		||||
 | 
			
		||||
  /* NB: a NULL redraw clip == full stage redraw */
 | 
			
		||||
  if (!redraw_clip)
 | 
			
		||||
@@ -652,16 +649,26 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
 | 
			
		||||
  else
 | 
			
		||||
    is_full_redraw = FALSE;
 | 
			
		||||
 | 
			
		||||
  may_use_clipped_redraw = FALSE;
 | 
			
		||||
  if (_clutter_stage_window_can_clip_redraws (stage_window) &&
 | 
			
		||||
      (can_blit_sub_buffer || has_buffer_age) &&
 | 
			
		||||
      !is_full_redraw &&
 | 
			
		||||
      /* some drivers struggle to get going and produce some junk
 | 
			
		||||
       * frames when starting up... */
 | 
			
		||||
      cogl_onscreen_get_frame_counter (COGL_ONSCREEN (fb)) > 3)
 | 
			
		||||
    {
 | 
			
		||||
      may_use_clipped_redraw = TRUE;
 | 
			
		||||
  may_use_clipped_redraw =
 | 
			
		||||
    _clutter_stage_window_can_clip_redraws (stage_window) &&
 | 
			
		||||
    (can_blit_sub_buffer || has_buffer_age) &&
 | 
			
		||||
    !is_full_redraw &&
 | 
			
		||||
    /* some drivers struggle to get going and produce some junk
 | 
			
		||||
     * frames when starting up... */
 | 
			
		||||
    cogl_onscreen_get_frame_counter (COGL_ONSCREEN (fb)) > 3;
 | 
			
		||||
 | 
			
		||||
  if (has_buffer_age)
 | 
			
		||||
    {
 | 
			
		||||
      buffer_age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (fb));
 | 
			
		||||
      if (!valid_buffer_age (view_cogl, buffer_age))
 | 
			
		||||
        {
 | 
			
		||||
          CLUTTER_NOTE (CLIPPING, "Invalid back buffer(age=%d): forcing full redraw\n", buffer_age);
 | 
			
		||||
          may_use_clipped_redraw = FALSE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (may_use_clipped_redraw)
 | 
			
		||||
    {
 | 
			
		||||
      fb_clip_region = offset_scale_and_clamp_region (redraw_clip,
 | 
			
		||||
                                                      -view_rect.x,
 | 
			
		||||
                                                      -view_rect.y,
 | 
			
		||||
@@ -702,8 +709,6 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
 | 
			
		||||
      redraw_clip = cairo_region_create_rectangle (&view_rect);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  queued_redraw_clip = cairo_region_copy (redraw_clip);
 | 
			
		||||
 | 
			
		||||
  if (may_use_clipped_redraw &&
 | 
			
		||||
      G_LIKELY (!(clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS)))
 | 
			
		||||
    use_clipped_redraw = TRUE;
 | 
			
		||||
@@ -717,64 +722,43 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
 | 
			
		||||
    {
 | 
			
		||||
      if (use_clipped_redraw && !clip_region_empty)
 | 
			
		||||
        {
 | 
			
		||||
          int age;
 | 
			
		||||
          cairo_region_t *fb_damage;
 | 
			
		||||
          cairo_region_t *view_damage;
 | 
			
		||||
          int i;
 | 
			
		||||
 | 
			
		||||
          age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (fb));
 | 
			
		||||
          fill_current_damage_history (view, fb_clip_region);
 | 
			
		||||
 | 
			
		||||
          if (valid_buffer_age (view_cogl, age))
 | 
			
		||||
          fb_damage = cairo_region_create ();
 | 
			
		||||
 | 
			
		||||
          for (i = 1; i <= buffer_age; i++)
 | 
			
		||||
            {
 | 
			
		||||
              cairo_region_t *fb_damage;
 | 
			
		||||
              cairo_region_t *view_damage;
 | 
			
		||||
              int i;
 | 
			
		||||
              int damage_index;
 | 
			
		||||
 | 
			
		||||
              fill_current_damage_history (view, fb_clip_region);
 | 
			
		||||
 | 
			
		||||
              fb_damage = cairo_region_create ();
 | 
			
		||||
 | 
			
		||||
              for (i = 1; i <= age; i++)
 | 
			
		||||
                {
 | 
			
		||||
                  int damage_index;
 | 
			
		||||
 | 
			
		||||
                  damage_index = DAMAGE_HISTORY (view_priv->damage_index - i - 1);
 | 
			
		||||
                  cairo_region_union (fb_damage,
 | 
			
		||||
                                      view_priv->damage_history[damage_index]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
              /* Update the fb clip region with the extra damage. */
 | 
			
		||||
              cairo_region_union (fb_clip_region, fb_damage);
 | 
			
		||||
 | 
			
		||||
              view_damage = offset_scale_and_clamp_region (fb_damage,
 | 
			
		||||
                                                           0, 0,
 | 
			
		||||
                                                           1.0f / fb_scale);
 | 
			
		||||
              cairo_region_translate (view_damage, view_rect.x, view_rect.y);
 | 
			
		||||
              cairo_region_intersect_rectangle (view_damage, &view_rect);
 | 
			
		||||
 | 
			
		||||
              /* Update the redraw clip region with the extra damage. */
 | 
			
		||||
              cairo_region_union (redraw_clip, view_damage);
 | 
			
		||||
 | 
			
		||||
              cairo_region_destroy (view_damage);
 | 
			
		||||
              cairo_region_destroy (fb_damage);
 | 
			
		||||
 | 
			
		||||
              CLUTTER_NOTE (CLIPPING, "Reusing back buffer(age=%d) - repairing region: num rects: %d\n",
 | 
			
		||||
                            age,
 | 
			
		||||
                            cairo_region_num_rectangles (fb_clip_region));
 | 
			
		||||
 | 
			
		||||
              swap_with_damage = TRUE;
 | 
			
		||||
              damage_index = DAMAGE_HISTORY (view_priv->damage_index - i - 1);
 | 
			
		||||
              cairo_region_union (fb_damage,
 | 
			
		||||
                                  view_priv->damage_history[damage_index]);
 | 
			
		||||
            }
 | 
			
		||||
          else
 | 
			
		||||
            {
 | 
			
		||||
              cairo_rectangle_int_t fb_damage;
 | 
			
		||||
 | 
			
		||||
              CLUTTER_NOTE (CLIPPING, "Invalid back buffer(age=%d): forcing full redraw\n", age);
 | 
			
		||||
              use_clipped_redraw = FALSE;
 | 
			
		||||
              fb_damage = (cairo_rectangle_int_t) {
 | 
			
		||||
                .x = 0,
 | 
			
		||||
                .y = 0,
 | 
			
		||||
                .width = ceilf (view_rect.width * fb_scale),
 | 
			
		||||
                .height = ceilf (view_rect.height * fb_scale)
 | 
			
		||||
              };
 | 
			
		||||
              fill_current_damage_history_rectangle (view, &fb_damage);
 | 
			
		||||
            }
 | 
			
		||||
          /* Update the fb clip region with the extra damage. */
 | 
			
		||||
          cairo_region_union (fb_clip_region, fb_damage);
 | 
			
		||||
 | 
			
		||||
          view_damage = offset_scale_and_clamp_region (fb_damage,
 | 
			
		||||
                                                       0, 0,
 | 
			
		||||
                                                       1.0f / fb_scale);
 | 
			
		||||
          cairo_region_translate (view_damage, view_rect.x, view_rect.y);
 | 
			
		||||
          cairo_region_intersect_rectangle (view_damage, &view_rect);
 | 
			
		||||
 | 
			
		||||
          /* Update the redraw clip region with the extra damage. */
 | 
			
		||||
          cairo_region_union (redraw_clip, view_damage);
 | 
			
		||||
 | 
			
		||||
          cairo_region_destroy (view_damage);
 | 
			
		||||
          cairo_region_destroy (fb_damage);
 | 
			
		||||
 | 
			
		||||
          CLUTTER_NOTE (CLIPPING, "Reusing back buffer(age=%d) - repairing region: num rects: %d\n",
 | 
			
		||||
                        buffer_age,
 | 
			
		||||
                        cairo_region_num_rectangles (fb_clip_region));
 | 
			
		||||
 | 
			
		||||
          swap_with_damage = TRUE;
 | 
			
		||||
        }
 | 
			
		||||
      else if (!use_clipped_redraw)
 | 
			
		||||
        {
 | 
			
		||||
@@ -934,7 +918,6 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&redraw_clip, cairo_region_destroy);
 | 
			
		||||
  g_clear_pointer (&queued_redraw_clip, cairo_region_destroy);
 | 
			
		||||
  g_clear_pointer (&fb_clip_region, cairo_region_destroy);
 | 
			
		||||
 | 
			
		||||
  if (do_swap_buffer)
 | 
			
		||||
@@ -955,11 +938,17 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
 | 
			
		||||
          swap_region = transformed_swap_region;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (queued_redraw_clip)
 | 
			
		||||
        {
 | 
			
		||||
          paint_damage_region (stage_window, view,
 | 
			
		||||
                               swap_region, queued_redraw_clip);
 | 
			
		||||
          cairo_region_destroy (queued_redraw_clip);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      res = swap_framebuffer (stage_window,
 | 
			
		||||
                              view,
 | 
			
		||||
                              swap_region,
 | 
			
		||||
                              swap_with_damage,
 | 
			
		||||
                              queued_redraw_clip);
 | 
			
		||||
                              swap_with_damage);
 | 
			
		||||
 | 
			
		||||
      cairo_region_destroy (swap_region);
 | 
			
		||||
 | 
			
		||||
@@ -967,10 +956,25 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      g_clear_pointer (&queued_redraw_clip, cairo_region_destroy);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_stage_cogl_scanout_view (ClutterStageCogl *stage_cogl,
 | 
			
		||||
                                 ClutterStageView *view,
 | 
			
		||||
                                 CoglScanout      *scanout)
 | 
			
		||||
{
 | 
			
		||||
  CoglFramebuffer *framebuffer = clutter_stage_view_get_framebuffer (view);
 | 
			
		||||
  CoglOnscreen *onscreen;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (cogl_is_onscreen (framebuffer));
 | 
			
		||||
 | 
			
		||||
  onscreen = COGL_ONSCREEN (framebuffer);
 | 
			
		||||
  cogl_onscreen_direct_scanout (onscreen, scanout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
 | 
			
		||||
{
 | 
			
		||||
@@ -983,11 +987,23 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
 | 
			
		||||
  for (l = _clutter_stage_window_get_views (stage_window); l; l = l->next)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterStageView *view = l->data;
 | 
			
		||||
      g_autoptr (CoglScanout) scanout = NULL;
 | 
			
		||||
 | 
			
		||||
      if (!clutter_stage_view_has_redraw_clip (view))
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      swap_event |= clutter_stage_cogl_redraw_view (stage_window, view);
 | 
			
		||||
      scanout = clutter_stage_view_take_scanout (view);
 | 
			
		||||
      if (scanout)
 | 
			
		||||
        {
 | 
			
		||||
          clutter_stage_cogl_scanout_view (stage_cogl,
 | 
			
		||||
                                           view,
 | 
			
		||||
                                           scanout);
 | 
			
		||||
          swap_event = TRUE;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          swap_event |= clutter_stage_cogl_redraw_view (stage_window, view);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  _clutter_stage_emit_after_paint (stage_cogl->wrapper);
 | 
			
		||||
 
 | 
			
		||||
@@ -30,8 +30,6 @@ clutter_headers = [
 | 
			
		||||
  'clutter-deform-effect.h',
 | 
			
		||||
  'clutter-deprecated.h',
 | 
			
		||||
  'clutter-desaturate-effect.h',
 | 
			
		||||
  'clutter-drag-action.h',
 | 
			
		||||
  'clutter-drop-action.h',
 | 
			
		||||
  'clutter-effect.h',
 | 
			
		||||
  'clutter-enums.h',
 | 
			
		||||
  'clutter-event.h',
 | 
			
		||||
@@ -118,8 +116,6 @@ clutter_sources = [
 | 
			
		||||
  'clutter-content.c',
 | 
			
		||||
  'clutter-deform-effect.c',
 | 
			
		||||
  'clutter-desaturate-effect.c',
 | 
			
		||||
  'clutter-drag-action.c',
 | 
			
		||||
  'clutter-drop-action.c',
 | 
			
		||||
  'clutter-effect.c',
 | 
			
		||||
  'clutter-event.c',
 | 
			
		||||
  'clutter-feature.c',
 | 
			
		||||
@@ -341,35 +337,20 @@ clutter_build_config_h = configure_file(
 | 
			
		||||
)
 | 
			
		||||
clutter_built_private_headers += clutter_build_config_h
 | 
			
		||||
 | 
			
		||||
clutter_config_defines = []
 | 
			
		||||
cdata = configuration_data()
 | 
			
		||||
if have_wayland
 | 
			
		||||
  clutter_config_defines += [
 | 
			
		||||
    '#define CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT 1',
 | 
			
		||||
  ]
 | 
			
		||||
  cdata.set10('CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT', true)
 | 
			
		||||
endif
 | 
			
		||||
if have_x11
 | 
			
		||||
  clutter_config_defines += [
 | 
			
		||||
    '#define CLUTTER_WINDOWING_X11 "x11"',
 | 
			
		||||
    '#define CLUTTER_INPUT_X11 "x11"',
 | 
			
		||||
    '#define CLUTTER_WINDOWING_GLX "glx"',
 | 
			
		||||
  ]
 | 
			
		||||
  cdata.set_quoted('CLUTTER_WINDOWING_X11', 'x11')
 | 
			
		||||
  cdata.set_quoted('CLUTTER_INPUT_X11', 'x11')
 | 
			
		||||
  cdata.set_quoted('CLUTTER_WINDOWING_GLX', 'glx')
 | 
			
		||||
endif
 | 
			
		||||
if have_native_backend
 | 
			
		||||
  clutter_config_defines += [
 | 
			
		||||
    '#define CLUTTER_WINDOWING_EGL "eglnative"',
 | 
			
		||||
    '#define CLUTTER_INPUT_EVDEV "evdev"',
 | 
			
		||||
  ]
 | 
			
		||||
  cdata.set_quoted('CLUTTER_WINDOWING_EGL', 'eglnative')
 | 
			
		||||
  cdata.set_quoted('CLUTTER_INPUT_EVDEV', 'evdev')
 | 
			
		||||
endif
 | 
			
		||||
clutter_config_defines += [
 | 
			
		||||
  '#define CLUTTER_INPUT_NULL "null"',
 | 
			
		||||
]
 | 
			
		||||
clutter_config_defines_string = ''
 | 
			
		||||
foreach clutter_config_define : clutter_config_defines
 | 
			
		||||
  clutter_config_defines_string += clutter_config_define + '\n'
 | 
			
		||||
endforeach
 | 
			
		||||
 | 
			
		||||
cdata = configuration_data()
 | 
			
		||||
cdata.set('CLUTTER_CONFIG_DEFINES', clutter_config_defines_string)
 | 
			
		||||
cdata.set_quoted('CLUTTER_INPUT_NULL', 'null')
 | 
			
		||||
 | 
			
		||||
clutter_config_h = configure_file(
 | 
			
		||||
  input: 'clutter-config.h.in',
 | 
			
		||||
@@ -429,7 +410,6 @@ libmutter_clutter = shared_library(libmutter_clutter_name,
 | 
			
		||||
  link_with: [
 | 
			
		||||
    libmutter_cogl,
 | 
			
		||||
    libmutter_cogl_pango,
 | 
			
		||||
    libmutter_cogl_path,
 | 
			
		||||
  ],
 | 
			
		||||
  install_rpath: pkglibdir,
 | 
			
		||||
  install_dir: pkglibdir,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								cogl/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								cogl/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -36,8 +36,6 @@ cogl-egl-defines.h
 | 
			
		||||
cogl-enum-types.c
 | 
			
		||||
cogl-enum-types.h
 | 
			
		||||
cogl-gl-header.h
 | 
			
		||||
cogl-path-enum-types.c
 | 
			
		||||
cogl-path-enum-types.h
 | 
			
		||||
cogl-config.h
 | 
			
		||||
cogl-config.h.in
 | 
			
		||||
cogl-mutter-config.h
 | 
			
		||||
 
 | 
			
		||||
@@ -81,6 +81,7 @@ struct _CoglPangoDisplayListNode
 | 
			
		||||
      GArray *rectangles;
 | 
			
		||||
      /* A primitive representing those vertices */
 | 
			
		||||
      CoglPrimitive *primitive;
 | 
			
		||||
      guint has_color : 1;
 | 
			
		||||
    } texture;
 | 
			
		||||
 | 
			
		||||
    struct
 | 
			
		||||
@@ -420,7 +421,9 @@ _cogl_pango_display_list_render (CoglFramebuffer *fb,
 | 
			
		||||
                                  cogl_color_get_red_byte (&node->color),
 | 
			
		||||
                                  cogl_color_get_green_byte (&node->color),
 | 
			
		||||
                                  cogl_color_get_blue_byte (&node->color),
 | 
			
		||||
                                  cogl_color_get_alpha_byte (color));
 | 
			
		||||
                                  (cogl_color_get_alpha_byte (&node->color) *
 | 
			
		||||
                                   cogl_color_get_alpha_byte (color) /
 | 
			
		||||
                                   255));
 | 
			
		||||
      else
 | 
			
		||||
        draw_color = *color;
 | 
			
		||||
      cogl_color_premultiply (&draw_color);
 | 
			
		||||
 
 | 
			
		||||
@@ -74,7 +74,7 @@ PangoFontMap *
 | 
			
		||||
cogl_pango_font_map_new (void)
 | 
			
		||||
{
 | 
			
		||||
  PangoFontMap *fm = pango_cairo_font_map_new ();
 | 
			
		||||
  CoglPangoFontMapPriv *priv = g_new0 (CoglPangoFontMapPriv, 1);
 | 
			
		||||
  g_autofree CoglPangoFontMapPriv *priv = g_new0 (CoglPangoFontMapPriv, 1);
 | 
			
		||||
 | 
			
		||||
  _COGL_GET_CONTEXT (context, NULL);
 | 
			
		||||
 | 
			
		||||
@@ -85,7 +85,7 @@ cogl_pango_font_map_new (void)
 | 
			
		||||
   * for now. */
 | 
			
		||||
  g_object_set_qdata_full (G_OBJECT (fm),
 | 
			
		||||
                           cogl_pango_font_map_get_priv_key (),
 | 
			
		||||
                           priv,
 | 
			
		||||
                           g_steal_pointer (&priv),
 | 
			
		||||
                           free_priv);
 | 
			
		||||
 | 
			
		||||
  return fm;
 | 
			
		||||
 
 | 
			
		||||
@@ -58,27 +58,29 @@ struct _CoglPangoGlyphCacheValue
 | 
			
		||||
 | 
			
		||||
  /* This will be set to TRUE when the glyph atlas is reorganized
 | 
			
		||||
     which means the glyph will need to be redrawn */
 | 
			
		||||
  gboolean   dirty;
 | 
			
		||||
  guint dirty : 1;
 | 
			
		||||
  /* Set to TRUE if the glyph has colors (eg. emoji) */
 | 
			
		||||
  guint has_color : 1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef void (* CoglPangoGlyphCacheDirtyFunc) (PangoFont *font,
 | 
			
		||||
                                               PangoGlyph glyph,
 | 
			
		||||
                                               CoglPangoGlyphCacheValue *value);
 | 
			
		||||
 | 
			
		||||
CoglPangoGlyphCache *
 | 
			
		||||
COGL_EXPORT CoglPangoGlyphCache *
 | 
			
		||||
cogl_pango_glyph_cache_new (CoglContext *ctx,
 | 
			
		||||
                            gboolean use_mipmapping);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_pango_glyph_cache_free (CoglPangoGlyphCache *cache);
 | 
			
		||||
 | 
			
		||||
CoglPangoGlyphCacheValue *
 | 
			
		||||
COGL_EXPORT CoglPangoGlyphCacheValue *
 | 
			
		||||
cogl_pango_glyph_cache_lookup (CoglPangoGlyphCache *cache,
 | 
			
		||||
                               gboolean             create,
 | 
			
		||||
                               PangoFont           *font,
 | 
			
		||||
                               PangoGlyph           glyph);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_pango_glyph_cache_clear (CoglPangoGlyphCache *cache);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 
 | 
			
		||||
@@ -50,6 +50,7 @@
 | 
			
		||||
#include <pango/pangocairo.h>
 | 
			
		||||
#include <pango/pango-renderer.h>
 | 
			
		||||
#include <cairo.h>
 | 
			
		||||
#include <cairo-ft.h>
 | 
			
		||||
 | 
			
		||||
#include "cogl/cogl-debug.h"
 | 
			
		||||
#include "cogl/cogl-context-private.h"
 | 
			
		||||
@@ -526,6 +527,24 @@ cogl_pango_renderer_get_cached_glyph (PangoRenderer *renderer,
 | 
			
		||||
                                        create, font, glyph);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
font_has_color_glyphs (const PangoFont *font)
 | 
			
		||||
{
 | 
			
		||||
  cairo_scaled_font_t *scaled_font;
 | 
			
		||||
  gboolean has_color = FALSE;
 | 
			
		||||
 | 
			
		||||
  scaled_font = pango_cairo_font_get_scaled_font ((PangoCairoFont *) font);
 | 
			
		||||
 | 
			
		||||
  if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_FT)
 | 
			
		||||
    {
 | 
			
		||||
      FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
 | 
			
		||||
      has_color = (FT_HAS_COLOR (ft_face) != 0);
 | 
			
		||||
      cairo_ft_scaled_font_unlock_face (scaled_font);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return has_color;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
cogl_pango_renderer_set_dirty_glyph (PangoFont *font,
 | 
			
		||||
                                     PangoGlyph glyph,
 | 
			
		||||
@@ -600,6 +619,8 @@ cogl_pango_renderer_set_dirty_glyph (PangoFont *font,
 | 
			
		||||
                           cairo_image_surface_get_data (surface));
 | 
			
		||||
 | 
			
		||||
  cairo_surface_destroy (surface);
 | 
			
		||||
 | 
			
		||||
  value->has_color = font_has_color_glyphs (font);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -698,6 +719,7 @@ cogl_pango_renderer_set_color_for_part (PangoRenderer   *renderer,
 | 
			
		||||
                                        PangoRenderPart  part)
 | 
			
		||||
{
 | 
			
		||||
  PangoColor *pango_color = pango_renderer_get_color (renderer, part);
 | 
			
		||||
  uint16_t alpha = pango_renderer_get_alpha (renderer, part);
 | 
			
		||||
  CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer);
 | 
			
		||||
 | 
			
		||||
  if (pango_color)
 | 
			
		||||
@@ -708,7 +730,7 @@ cogl_pango_renderer_set_color_for_part (PangoRenderer   *renderer,
 | 
			
		||||
                                pango_color->red >> 8,
 | 
			
		||||
                                pango_color->green >> 8,
 | 
			
		||||
                                pango_color->blue >> 8,
 | 
			
		||||
                                0xff);
 | 
			
		||||
                                alpha ? alpha >> 8 : 0xff);
 | 
			
		||||
 | 
			
		||||
      _cogl_pango_display_list_set_color_override (priv->display_list, &color);
 | 
			
		||||
    }
 | 
			
		||||
@@ -820,14 +842,13 @@ cogl_pango_renderer_draw_glyphs (PangoRenderer    *renderer,
 | 
			
		||||
  CoglPangoGlyphCacheValue *cache_value;
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  cogl_pango_renderer_set_color_for_part (renderer,
 | 
			
		||||
					  PANGO_RENDER_PART_FOREGROUND);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < glyphs->num_glyphs; i++)
 | 
			
		||||
    {
 | 
			
		||||
      PangoGlyphInfo *gi = glyphs->glyphs + i;
 | 
			
		||||
      float x, y;
 | 
			
		||||
 | 
			
		||||
      cogl_pango_renderer_set_color_for_part (renderer,
 | 
			
		||||
                                              PANGO_RENDER_PART_FOREGROUND);
 | 
			
		||||
      cogl_pango_renderer_get_device_units (renderer,
 | 
			
		||||
					    xi + gi->geometry.x_offset,
 | 
			
		||||
					    yi + gi->geometry.y_offset,
 | 
			
		||||
@@ -884,6 +905,19 @@ cogl_pango_renderer_draw_glyphs (PangoRenderer    *renderer,
 | 
			
		||||
	      x += (float)(cache_value->draw_x);
 | 
			
		||||
	      y += (float)(cache_value->draw_y);
 | 
			
		||||
 | 
			
		||||
              /* Do not override color if the glyph/font provide its own */
 | 
			
		||||
              if (cache_value->has_color)
 | 
			
		||||
                {
 | 
			
		||||
                  CoglColor color;
 | 
			
		||||
                  uint16_t alpha;
 | 
			
		||||
 | 
			
		||||
                  alpha = pango_renderer_get_alpha (renderer,
 | 
			
		||||
                                                    PANGO_RENDER_PART_FOREGROUND);
 | 
			
		||||
                  cogl_color_init_from_4ub (&color, 0xff, 0xff, 0xff,
 | 
			
		||||
					    alpha ? alpha >> 8 : 0xff);
 | 
			
		||||
                  _cogl_pango_display_list_set_color_override (priv->display_list, &color);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
              cogl_pango_renderer_draw_glyph (priv, cache_value, x, y);
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -75,7 +75,7 @@ typedef PangoCairoFontMap CoglPangoFontMap;
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.14
 | 
			
		||||
 */
 | 
			
		||||
PangoFontMap *
 | 
			
		||||
COGL_EXPORT PangoFontMap *
 | 
			
		||||
cogl_pango_font_map_new (void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -86,7 +86,7 @@ cogl_pango_font_map_new (void);
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer full): the newly created context: free with g_object_unref().
 | 
			
		||||
 */
 | 
			
		||||
PangoContext *
 | 
			
		||||
COGL_EXPORT PangoContext *
 | 
			
		||||
cogl_pango_font_map_create_context (CoglPangoFontMap *font_map);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -102,7 +102,7 @@ cogl_pango_font_map_create_context (CoglPangoFontMap *font_map);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.14
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_pango_font_map_set_resolution (CoglPangoFontMap *font_map,
 | 
			
		||||
                                    double dpi);
 | 
			
		||||
 | 
			
		||||
@@ -114,7 +114,7 @@ cogl_pango_font_map_set_resolution (CoglPangoFontMap *font_map,
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_pango_font_map_clear_glyph_cache (CoglPangoFontMap *font_map);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -129,7 +129,7 @@ cogl_pango_font_map_clear_glyph_cache (CoglPangoFontMap *font_map);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_pango_ensure_glyph_cache_for_layout (PangoLayout *layout);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -142,7 +142,7 @@ cogl_pango_ensure_glyph_cache_for_layout (PangoLayout *layout);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_pango_font_map_set_use_mipmapping (CoglPangoFontMap *font_map,
 | 
			
		||||
                                        gboolean value);
 | 
			
		||||
 | 
			
		||||
@@ -157,7 +157,7 @@ cogl_pango_font_map_set_use_mipmapping (CoglPangoFontMap *font_map,
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
COGL_EXPORT gboolean
 | 
			
		||||
cogl_pango_font_map_get_use_mipmapping (CoglPangoFontMap *font_map);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -170,7 +170,7 @@ cogl_pango_font_map_get_use_mipmapping (CoglPangoFontMap *font_map);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
PangoRenderer *
 | 
			
		||||
COGL_EXPORT PangoRenderer *
 | 
			
		||||
cogl_pango_font_map_get_renderer (CoglPangoFontMap *font_map);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -187,7 +187,7 @@ cogl_pango_font_map_get_renderer (CoglPangoFontMap *font_map);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.14
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_pango_show_layout (CoglFramebuffer *framebuffer,
 | 
			
		||||
                        PangoLayout *layout,
 | 
			
		||||
                        float x,
 | 
			
		||||
@@ -208,7 +208,7 @@ cogl_pango_show_layout (CoglFramebuffer *framebuffer,
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.14
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_pango_show_layout_line (CoglFramebuffer *framebuffer,
 | 
			
		||||
                             PangoLayoutLine *line,
 | 
			
		||||
                             float x,
 | 
			
		||||
@@ -227,7 +227,7 @@ cogl_pango_show_layout_line (CoglFramebuffer *framebuffer,
 | 
			
		||||
typedef struct _CoglPangoRenderer      CoglPangoRenderer;
 | 
			
		||||
typedef struct _CoglPangoRendererClass CoglPangoRendererClass;
 | 
			
		||||
 | 
			
		||||
GType cogl_pango_renderer_get_type (void) G_GNUC_CONST;
 | 
			
		||||
COGL_EXPORT GType cogl_pango_renderer_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
global:
 | 
			
		||||
  cogl_pango_*;
 | 
			
		||||
local:
 | 
			
		||||
  *;
 | 
			
		||||
};
 | 
			
		||||
@@ -20,19 +20,13 @@ cogl_pango_deps = [
 | 
			
		||||
  libmutter_cogl_dep,
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
libmutter_cogl_pango_map = 'libmutter-cogl-pango.map'
 | 
			
		||||
libmutter_cogl_pango_link_args = [
 | 
			
		||||
  '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(),
 | 
			
		||||
      libmutter_cogl_pango_map),
 | 
			
		||||
]
 | 
			
		||||
libmutter_cogl_pango = shared_library('mutter-cogl-pango-' + libmutter_api_version,
 | 
			
		||||
  sources: [cogl_pango_sources, cogl_pango_public_headers],
 | 
			
		||||
  version: '0.0.0',
 | 
			
		||||
  soversion: 0,
 | 
			
		||||
  c_args: cogl_c_args,
 | 
			
		||||
  include_directories: [cogl_includepath, cogl_path_includepath],
 | 
			
		||||
  link_depends: libmutter_cogl_pango_map,
 | 
			
		||||
  link_args: libmutter_cogl_pango_link_args,
 | 
			
		||||
  include_directories: [cogl_includepath],
 | 
			
		||||
  gnu_symbol_visibility: 'hidden',
 | 
			
		||||
  dependencies: [cogl_pango_deps],
 | 
			
		||||
  install_rpath: pkglibdir,
 | 
			
		||||
  install_dir: pkglibdir,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,48 +0,0 @@
 | 
			
		||||
/*** BEGIN file-header ***/
 | 
			
		||||
#include "cogl-config.h"
 | 
			
		||||
 | 
			
		||||
/* We need to undefine this so that we will be sure to include
 | 
			
		||||
 * cogl-path.h instead of cogl2-path.h when we include the framebuffer
 | 
			
		||||
 * header. Otherwise it will include both headers and it won't
 | 
			
		||||
 * compile. */
 | 
			
		||||
#undef COGL_ENABLE_EXPERIMENTAL_2_0_API
 | 
			
		||||
 | 
			
		||||
#include "cogl-path-enum-types.h"
 | 
			
		||||
/*** END file-header ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN file-production ***/
 | 
			
		||||
 | 
			
		||||
/* enumerations from "@filename@" */
 | 
			
		||||
#include "@filename@"
 | 
			
		||||
 | 
			
		||||
/*** END file-production ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN value-header ***/
 | 
			
		||||
GType
 | 
			
		||||
@enum_name@_get_type (void)
 | 
			
		||||
{
 | 
			
		||||
  static volatile gsize g_enum_type_id__volatile = 0;
 | 
			
		||||
 | 
			
		||||
  if (g_once_init_enter (&g_enum_type_id__volatile))
 | 
			
		||||
    {
 | 
			
		||||
      static const G@Type@Value values[] = {
 | 
			
		||||
/*** END value-header ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN value-production ***/
 | 
			
		||||
        { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
 | 
			
		||||
/*** END value-production ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN value-tail ***/
 | 
			
		||||
        { 0, NULL, NULL }
 | 
			
		||||
      };
 | 
			
		||||
      GType g_enum_type_id;
 | 
			
		||||
 | 
			
		||||
      g_enum_type_id =
 | 
			
		||||
        g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
 | 
			
		||||
 | 
			
		||||
      g_once_init_leave (&g_enum_type_id__volatile, g_enum_type_id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return g_enum_type_id__volatile;
 | 
			
		||||
}
 | 
			
		||||
/*** END value-tail ***/
 | 
			
		||||
@@ -1,25 +0,0 @@
 | 
			
		||||
/*** BEGIN file-header ***/
 | 
			
		||||
#ifndef __COGL_PATH_ENUM_TYPES_H__
 | 
			
		||||
#define __COGL_PATH_ENUM_TYPES_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/*** END file-header ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN file-production ***/
 | 
			
		||||
/* enumerations from "@basename@" */
 | 
			
		||||
/*** END file-production ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN file-tail ***/
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __COGL_PATH_ENUM_TYPES_H__ */
 | 
			
		||||
/*** END file-tail ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN value-header ***/
 | 
			
		||||
GType @enum_name@_get_type (void) G_GNUC_CONST;
 | 
			
		||||
#define COGL_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
 | 
			
		||||
 | 
			
		||||
/*** END value-header ***/
 | 
			
		||||
@@ -1,486 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Cogl
 | 
			
		||||
 *
 | 
			
		||||
 * A Low Level GPU Graphics and Utilities API
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2008,2009,2013 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person
 | 
			
		||||
 * obtaining a copy of this software and associated documentation
 | 
			
		||||
 * files (the "Software"), to deal in the Software without
 | 
			
		||||
 * restriction, including without limitation the rights to use, copy,
 | 
			
		||||
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 | 
			
		||||
 * of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be
 | 
			
		||||
 * included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
			
		||||
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
			
		||||
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
			
		||||
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION)
 | 
			
		||||
#error "Only <cogl/cogl.h> can be included directly."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef __COGL_PATH_FUNCTIONS_H__
 | 
			
		||||
#define __COGL_PATH_FUNCTIONS_H__
 | 
			
		||||
 | 
			
		||||
#include <cogl/cogl-types.h>
 | 
			
		||||
#ifdef COGL_COMPILATION
 | 
			
		||||
#include "cogl-context.h"
 | 
			
		||||
#else
 | 
			
		||||
#include <cogl/cogl.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_path_get_gtype:
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: a #GType that can be used with the GLib type system.
 | 
			
		||||
 */
 | 
			
		||||
GType cogl_path_get_gtype (void);
 | 
			
		||||
 | 
			
		||||
#define cogl_path_new cogl2_path_new
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_path_new:
 | 
			
		||||
 *
 | 
			
		||||
 * Creates a new, empty path object. The default fill rule is
 | 
			
		||||
 * %COGL_PATH_FILL_RULE_EVEN_ODD.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: A pointer to a newly allocated #CoglPath, which can
 | 
			
		||||
 * be freed using cogl_object_unref().
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.0
 | 
			
		||||
 */
 | 
			
		||||
CoglPath *
 | 
			
		||||
cogl_path_new (void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_path_copy:
 | 
			
		||||
 * @path: A #CoglPath object
 | 
			
		||||
 *
 | 
			
		||||
 * Returns a new copy of the path in @path. The new path has a
 | 
			
		||||
 * reference count of 1 so you should unref it with
 | 
			
		||||
 * cogl_object_unref() if you no longer need it.
 | 
			
		||||
 *
 | 
			
		||||
 * Internally the path will share the data until one of the paths is
 | 
			
		||||
 * modified so copying paths should be relatively cheap.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: (transfer full): a copy of the path in @path.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.0
 | 
			
		||||
 */
 | 
			
		||||
CoglPath *
 | 
			
		||||
cogl_path_copy (CoglPath *path);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_is_path:
 | 
			
		||||
 * @object: A #CoglObject
 | 
			
		||||
 *
 | 
			
		||||
 * Gets whether the given object references an existing path object.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: %TRUE if the object references a #CoglPath,
 | 
			
		||||
 *   %FALSE otherwise.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.0
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
cogl_is_path (void *object);
 | 
			
		||||
 | 
			
		||||
#define cogl_path_move_to cogl2_path_move_to
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_path_move_to:
 | 
			
		||||
 * @x: X coordinate of the pen location to move to.
 | 
			
		||||
 * @y: Y coordinate of the pen location to move to.
 | 
			
		||||
 *
 | 
			
		||||
 * Moves the pen to the given location. If there is an existing path
 | 
			
		||||
 * this will start a new disjoint subpath.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.0
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
cogl_path_move_to (CoglPath *path,
 | 
			
		||||
                   float x,
 | 
			
		||||
                   float y);
 | 
			
		||||
 | 
			
		||||
#define cogl_path_rel_move_to cogl2_path_rel_move_to
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_path_rel_move_to:
 | 
			
		||||
 * @x: X offset from the current pen location to move the pen to.
 | 
			
		||||
 * @y: Y offset from the current pen location to move the pen to.
 | 
			
		||||
 *
 | 
			
		||||
 * Moves the pen to the given offset relative to the current pen
 | 
			
		||||
 * location. If there is an existing path this will start a new
 | 
			
		||||
 * disjoint subpath.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.0
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
cogl_path_rel_move_to (CoglPath *path,
 | 
			
		||||
                       float x,
 | 
			
		||||
                       float y);
 | 
			
		||||
 | 
			
		||||
#define cogl_path_line_to cogl2_path_line_to
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_path_line_to:
 | 
			
		||||
 * @x: X coordinate of the end line vertex
 | 
			
		||||
 * @y: Y coordinate of the end line vertex
 | 
			
		||||
 *
 | 
			
		||||
 * Adds a straight line segment to the current path that ends at the
 | 
			
		||||
 * given coordinates.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.0
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
cogl_path_line_to (CoglPath *path,
 | 
			
		||||
                   float x,
 | 
			
		||||
                   float y);
 | 
			
		||||
 | 
			
		||||
#define cogl_path_rel_line_to cogl2_path_rel_line_to
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_path_rel_line_to:
 | 
			
		||||
 * @x: X offset from the current pen location of the end line vertex
 | 
			
		||||
 * @y: Y offset from the current pen location of the end line vertex
 | 
			
		||||
 *
 | 
			
		||||
 * Adds a straight line segment to the current path that ends at the
 | 
			
		||||
 * given coordinates relative to the current pen location.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.0
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
cogl_path_rel_line_to (CoglPath *path,
 | 
			
		||||
                       float x,
 | 
			
		||||
                       float y);
 | 
			
		||||
 | 
			
		||||
#define cogl_path_arc cogl2_path_arc
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_path_arc:
 | 
			
		||||
 * @center_x: X coordinate of the elliptical arc center
 | 
			
		||||
 * @center_y: Y coordinate of the elliptical arc center
 | 
			
		||||
 * @radius_x: X radius of the elliptical arc
 | 
			
		||||
 * @radius_y: Y radius of the elliptical arc
 | 
			
		||||
 * @angle_1: Angle in degrees at which the arc begin
 | 
			
		||||
 * @angle_2: Angle in degrees at which the arc ends
 | 
			
		||||
 *
 | 
			
		||||
 * Adds an elliptical arc segment to the current path. A straight line
 | 
			
		||||
 * segment will link the current pen location with the first vertex
 | 
			
		||||
 * of the arc. If you perform a move_to to the arcs start just before
 | 
			
		||||
 * drawing it you create a free standing arc.
 | 
			
		||||
 *
 | 
			
		||||
 * The angles are measured in degrees where 0° is in the direction of
 | 
			
		||||
 * the positive X axis and 90° is in the direction of the positive Y
 | 
			
		||||
 * axis. The angle of the arc begins at @angle_1 and heads towards
 | 
			
		||||
 * @angle_2 (so if @angle_2 is less than @angle_1 it will decrease,
 | 
			
		||||
 * otherwise it will increase).
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.0
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
cogl_path_arc (CoglPath *path,
 | 
			
		||||
               float center_x,
 | 
			
		||||
               float center_y,
 | 
			
		||||
               float radius_x,
 | 
			
		||||
               float radius_y,
 | 
			
		||||
               float angle_1,
 | 
			
		||||
               float angle_2);
 | 
			
		||||
 | 
			
		||||
#define cogl_path_curve_to cogl2_path_curve_to
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_path_curve_to:
 | 
			
		||||
 * @x_1: X coordinate of the second bezier control point
 | 
			
		||||
 * @y_1: Y coordinate of the second bezier control point
 | 
			
		||||
 * @x_2: X coordinate of the third bezier control point
 | 
			
		||||
 * @y_2: Y coordinate of the third bezier control point
 | 
			
		||||
 * @x_3: X coordinate of the fourth bezier control point
 | 
			
		||||
 * @y_3: Y coordinate of the fourth bezier control point
 | 
			
		||||
 *
 | 
			
		||||
 * Adds a cubic bezier curve segment to the current path with the given
 | 
			
		||||
 * second, third and fourth control points and using current pen location
 | 
			
		||||
 * as the first control point.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.0
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
cogl_path_curve_to (CoglPath *path,
 | 
			
		||||
                    float x_1,
 | 
			
		||||
                    float y_1,
 | 
			
		||||
                    float x_2,
 | 
			
		||||
                    float y_2,
 | 
			
		||||
                    float x_3,
 | 
			
		||||
                    float y_3);
 | 
			
		||||
 | 
			
		||||
#define cogl_path_rel_curve_to cogl2_path_rel_curve_to
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_path_rel_curve_to:
 | 
			
		||||
 * @x_1: X coordinate of the second bezier control point
 | 
			
		||||
 * @y_1: Y coordinate of the second bezier control point
 | 
			
		||||
 * @x_2: X coordinate of the third bezier control point
 | 
			
		||||
 * @y_2: Y coordinate of the third bezier control point
 | 
			
		||||
 * @x_3: X coordinate of the fourth bezier control point
 | 
			
		||||
 * @y_3: Y coordinate of the fourth bezier control point
 | 
			
		||||
 *
 | 
			
		||||
 * Adds a cubic bezier curve segment to the current path with the given
 | 
			
		||||
 * second, third and fourth control points and using current pen location
 | 
			
		||||
 * as the first control point. The given coordinates are relative to the
 | 
			
		||||
 * current pen location.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.0
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
cogl_path_rel_curve_to (CoglPath *path,
 | 
			
		||||
                        float x_1,
 | 
			
		||||
                        float y_1,
 | 
			
		||||
                        float x_2,
 | 
			
		||||
                        float y_2,
 | 
			
		||||
                        float x_3,
 | 
			
		||||
                        float y_3);
 | 
			
		||||
 | 
			
		||||
#define cogl_path_close cogl2_path_close
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_path_close:
 | 
			
		||||
 *
 | 
			
		||||
 * Closes the path being constructed by adding a straight line segment
 | 
			
		||||
 * to it that ends at the first vertex of the path.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.0
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
cogl_path_close (CoglPath *path);
 | 
			
		||||
 | 
			
		||||
#define cogl_path_line cogl2_path_line
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_path_line:
 | 
			
		||||
 * @x_1: X coordinate of the start line vertex
 | 
			
		||||
 * @y_1: Y coordinate of the start line vertex
 | 
			
		||||
 * @x_2: X coordinate of the end line vertex
 | 
			
		||||
 * @y_2: Y coordinate of the end line vertex
 | 
			
		||||
 *
 | 
			
		||||
 * Constructs a straight line shape starting and ending at the given
 | 
			
		||||
 * coordinates. If there is an existing path this will start a new
 | 
			
		||||
 * disjoint sub-path.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.0
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
cogl_path_line (CoglPath *path,
 | 
			
		||||
                float x_1,
 | 
			
		||||
                float y_1,
 | 
			
		||||
                float x_2,
 | 
			
		||||
                float y_2);
 | 
			
		||||
 | 
			
		||||
#define cogl_path_polyline cogl2_path_polyline
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_path_polyline:
 | 
			
		||||
 * @coords: (in) (array) (transfer none): A pointer to the first element of an
 | 
			
		||||
 * array of fixed-point values that specify the vertex coordinates.
 | 
			
		||||
 * @num_points: The total number of vertices.
 | 
			
		||||
 *
 | 
			
		||||
 * Constructs a series of straight line segments, starting from the
 | 
			
		||||
 * first given vertex coordinate. If there is an existing path this
 | 
			
		||||
 * will start a new disjoint sub-path. Each subsequent segment starts
 | 
			
		||||
 * where the previous one ended and ends at the next given vertex
 | 
			
		||||
 * coordinate.
 | 
			
		||||
 *
 | 
			
		||||
 * The coords array must contain 2 * num_points values. The first value
 | 
			
		||||
 * represents the X coordinate of the first vertex, the second value
 | 
			
		||||
 * represents the Y coordinate of the first vertex, continuing in the same
 | 
			
		||||
 * fashion for the rest of the vertices. (num_points - 1) segments will
 | 
			
		||||
 * be constructed.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.0
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
cogl_path_polyline (CoglPath *path,
 | 
			
		||||
                    const float *coords,
 | 
			
		||||
                    int num_points);
 | 
			
		||||
 | 
			
		||||
#define cogl_path_polygon cogl2_path_polygon
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_path_polygon:
 | 
			
		||||
 * @coords: (in) (array) (transfer none): A pointer to the first element of
 | 
			
		||||
 * an array of fixed-point values that specify the vertex coordinates.
 | 
			
		||||
 * @num_points: The total number of vertices.
 | 
			
		||||
 *
 | 
			
		||||
 * Constructs a polygonal shape of the given number of vertices. If
 | 
			
		||||
 * there is an existing path this will start a new disjoint sub-path.
 | 
			
		||||
 *
 | 
			
		||||
 * The coords array must contain 2 * num_points values. The first value
 | 
			
		||||
 * represents the X coordinate of the first vertex, the second value
 | 
			
		||||
 * represents the Y coordinate of the first vertex, continuing in the same
 | 
			
		||||
 * fashion for the rest of the vertices.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.0
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
cogl_path_polygon (CoglPath *path,
 | 
			
		||||
                   const float *coords,
 | 
			
		||||
                   int num_points);
 | 
			
		||||
 | 
			
		||||
#define cogl_path_rectangle cogl2_path_rectangle
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_path_rectangle:
 | 
			
		||||
 * @x_1: X coordinate of the top-left corner.
 | 
			
		||||
 * @y_1: Y coordinate of the top-left corner.
 | 
			
		||||
 * @x_2: X coordinate of the bottom-right corner.
 | 
			
		||||
 * @y_2: Y coordinate of the bottom-right corner.
 | 
			
		||||
 *
 | 
			
		||||
 * Constructs a rectangular shape at the given coordinates. If there
 | 
			
		||||
 * is an existing path this will start a new disjoint sub-path.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.0
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
cogl_path_rectangle (CoglPath *path,
 | 
			
		||||
                     float x_1,
 | 
			
		||||
                     float y_1,
 | 
			
		||||
                     float x_2,
 | 
			
		||||
                     float y_2);
 | 
			
		||||
 | 
			
		||||
#define cogl_path_ellipse cogl2_path_ellipse
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_path_ellipse:
 | 
			
		||||
 * @center_x: X coordinate of the ellipse center
 | 
			
		||||
 * @center_y: Y coordinate of the ellipse center
 | 
			
		||||
 * @radius_x: X radius of the ellipse
 | 
			
		||||
 * @radius_y: Y radius of the ellipse
 | 
			
		||||
 *
 | 
			
		||||
 * Constructs an ellipse shape. If there is an existing path this will
 | 
			
		||||
 * start a new disjoint sub-path.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.0
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
cogl_path_ellipse (CoglPath *path,
 | 
			
		||||
                   float center_x,
 | 
			
		||||
                   float center_y,
 | 
			
		||||
                   float radius_x,
 | 
			
		||||
                   float radius_y);
 | 
			
		||||
 | 
			
		||||
#define cogl_path_round_rectangle cogl2_path_round_rectangle
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_path_round_rectangle:
 | 
			
		||||
 * @x_1: X coordinate of the top-left corner.
 | 
			
		||||
 * @y_1: Y coordinate of the top-left corner.
 | 
			
		||||
 * @x_2: X coordinate of the bottom-right corner.
 | 
			
		||||
 * @y_2: Y coordinate of the bottom-right corner.
 | 
			
		||||
 * @radius: Radius of the corner arcs.
 | 
			
		||||
 * @arc_step: Angle increment resolution for subdivision of
 | 
			
		||||
 * the corner arcs.
 | 
			
		||||
 *
 | 
			
		||||
 * Constructs a rectangular shape with rounded corners. If there is an
 | 
			
		||||
 * existing path this will start a new disjoint sub-path.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.0
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
cogl_path_round_rectangle (CoglPath *path,
 | 
			
		||||
                           float x_1,
 | 
			
		||||
                           float y_1,
 | 
			
		||||
                           float x_2,
 | 
			
		||||
                           float y_2,
 | 
			
		||||
                           float radius,
 | 
			
		||||
                           float arc_step);
 | 
			
		||||
 | 
			
		||||
#define cogl_path_set_fill_rule cogl2_path_set_fill_rule
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_path_set_fill_rule:
 | 
			
		||||
 * @fill_rule: The new fill rule.
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the fill rule of the current path to @fill_rule. This will
 | 
			
		||||
 * affect how the path is filled when cogl_path_fill() is later
 | 
			
		||||
 * called. Note that the fill rule state is attached to the path so
 | 
			
		||||
 * calling cogl_get_path() will preserve the fill rule and calling
 | 
			
		||||
 * cogl_path_new() will reset the fill rule back to the default.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.0
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
cogl_path_set_fill_rule (CoglPath *path, CoglPathFillRule fill_rule);
 | 
			
		||||
 | 
			
		||||
#define cogl_path_get_fill_rule cogl2_path_get_fill_rule
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_path_get_fill_rule:
 | 
			
		||||
 *
 | 
			
		||||
 * Retrieves the fill rule set using cogl_path_set_fill_rule().
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the fill rule that is used for the current path.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.0
 | 
			
		||||
 */
 | 
			
		||||
CoglPathFillRule
 | 
			
		||||
cogl_path_get_fill_rule (CoglPath *path);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_framebuffer_fill_path:
 | 
			
		||||
 * @framebuffer: A #CoglFramebuffer
 | 
			
		||||
 * @pipeline: A #CoglPipeline to render with
 | 
			
		||||
 * @path: The #CoglPath to fill
 | 
			
		||||
 *
 | 
			
		||||
 * Fills the interior of the path using the fragment operations
 | 
			
		||||
 * defined by the pipeline.
 | 
			
		||||
 *
 | 
			
		||||
 * The interior of the shape is determined using the fill rule of the
 | 
			
		||||
 * path. See %CoglPathFillRule for details.
 | 
			
		||||
 *
 | 
			
		||||
 * <note>The result of referencing sliced textures in your current
 | 
			
		||||
 * pipeline when filling a path are undefined. You should pass
 | 
			
		||||
 * the %COGL_TEXTURE_NO_SLICING flag when loading any texture you will
 | 
			
		||||
 * use while filling a path.</note>
 | 
			
		||||
 *
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer,
 | 
			
		||||
                            CoglPipeline *pipeline,
 | 
			
		||||
                            CoglPath *path);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_framebuffer_stroke_path:
 | 
			
		||||
 * @framebuffer: A #CoglFramebuffer
 | 
			
		||||
 * @pipeline: A #CoglPipeline to render with
 | 
			
		||||
 * @path: The #CoglPath to stroke
 | 
			
		||||
 *
 | 
			
		||||
 * Strokes the edge of the path using the fragment operations defined
 | 
			
		||||
 * by the pipeline. The stroke line will have a width of 1 pixel
 | 
			
		||||
 * regardless of the current transformation matrix.
 | 
			
		||||
 *
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
cogl_framebuffer_stroke_path (CoglFramebuffer *framebuffer,
 | 
			
		||||
                              CoglPipeline *pipeline,
 | 
			
		||||
                              CoglPath *path);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_framebuffer_push_path_clip:
 | 
			
		||||
 * @framebuffer: A #CoglFramebuffer pointer
 | 
			
		||||
 * @path: The path to clip with.
 | 
			
		||||
 *
 | 
			
		||||
 * Sets a new clipping area using the silhouette of the specified,
 | 
			
		||||
 * filled @path.  The clipping area is intersected with the previous
 | 
			
		||||
 * clipping area. To restore the previous clipping area, call
 | 
			
		||||
 * cogl_framebuffer_pop_clip().
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
cogl_framebuffer_push_path_clip (CoglFramebuffer *framebuffer,
 | 
			
		||||
                                 CoglPath *path);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __COGL_PATH_FUNCTIONS_H__ */
 | 
			
		||||
 | 
			
		||||
@@ -1,126 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Cogl
 | 
			
		||||
 *
 | 
			
		||||
 * A Low Level GPU Graphics and Utilities API
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2010 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person
 | 
			
		||||
 * obtaining a copy of this software and associated documentation
 | 
			
		||||
 * files (the "Software"), to deal in the Software without
 | 
			
		||||
 * restriction, including without limitation the rights to use, copy,
 | 
			
		||||
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 | 
			
		||||
 * of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be
 | 
			
		||||
 * included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
			
		||||
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
			
		||||
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
			
		||||
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __COGL_PATH_PRIVATE_H
 | 
			
		||||
#define __COGL_PATH_PRIVATE_H
 | 
			
		||||
 | 
			
		||||
#include "cogl-object.h"
 | 
			
		||||
#include "cogl-attribute-private.h"
 | 
			
		||||
 | 
			
		||||
typedef struct _floatVec2
 | 
			
		||||
{
 | 
			
		||||
  float x;
 | 
			
		||||
  float y;
 | 
			
		||||
} floatVec2;
 | 
			
		||||
 | 
			
		||||
typedef struct _CoglPathNode
 | 
			
		||||
{
 | 
			
		||||
  float x;
 | 
			
		||||
  float y;
 | 
			
		||||
  unsigned int path_size;
 | 
			
		||||
} CoglPathNode;
 | 
			
		||||
 | 
			
		||||
typedef struct _CoglBezQuad
 | 
			
		||||
{
 | 
			
		||||
  floatVec2 p1;
 | 
			
		||||
  floatVec2 p2;
 | 
			
		||||
  floatVec2 p3;
 | 
			
		||||
} CoglBezQuad;
 | 
			
		||||
 | 
			
		||||
typedef struct _CoglBezCubic
 | 
			
		||||
{
 | 
			
		||||
  floatVec2 p1;
 | 
			
		||||
  floatVec2 p2;
 | 
			
		||||
  floatVec2 p3;
 | 
			
		||||
  floatVec2 p4;
 | 
			
		||||
} CoglBezCubic;
 | 
			
		||||
 | 
			
		||||
typedef struct _CoglPathData CoglPathData;
 | 
			
		||||
 | 
			
		||||
struct _CoglPath
 | 
			
		||||
{
 | 
			
		||||
  CoglObject _parent;
 | 
			
		||||
 | 
			
		||||
  CoglPathData *data;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define COGL_PATH_N_ATTRIBUTES 2
 | 
			
		||||
 | 
			
		||||
struct _CoglPathData
 | 
			
		||||
{
 | 
			
		||||
  unsigned int         ref_count;
 | 
			
		||||
 | 
			
		||||
  CoglContext         *context;
 | 
			
		||||
 | 
			
		||||
  CoglPathFillRule     fill_rule;
 | 
			
		||||
 | 
			
		||||
  GArray              *path_nodes;
 | 
			
		||||
 | 
			
		||||
  floatVec2            path_start;
 | 
			
		||||
  floatVec2            path_pen;
 | 
			
		||||
  unsigned int         last_path;
 | 
			
		||||
  floatVec2            path_nodes_min;
 | 
			
		||||
  floatVec2            path_nodes_max;
 | 
			
		||||
 | 
			
		||||
  CoglAttributeBuffer *fill_attribute_buffer;
 | 
			
		||||
  CoglIndices         *fill_vbo_indices;
 | 
			
		||||
  unsigned int         fill_vbo_n_indices;
 | 
			
		||||
  CoglAttribute       *fill_attributes[COGL_PATH_N_ATTRIBUTES + 1];
 | 
			
		||||
  CoglPrimitive       *fill_primitive;
 | 
			
		||||
 | 
			
		||||
  CoglAttributeBuffer *stroke_attribute_buffer;
 | 
			
		||||
  CoglAttribute      **stroke_attributes;
 | 
			
		||||
  unsigned int         stroke_n_attributes;
 | 
			
		||||
 | 
			
		||||
  /* This is used as an optimisation for when the path contains a
 | 
			
		||||
     single contour specified using cogl2_path_rectangle. Cogl is more
 | 
			
		||||
     optimised to handle rectangles than paths so we can detect this
 | 
			
		||||
     case and divert to the journal or a rectangle clip. If it is TRUE
 | 
			
		||||
     then the entire path can be described by calling
 | 
			
		||||
     _cogl_path_get_bounds */
 | 
			
		||||
  gboolean             is_rectangle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_cogl_add_path_to_stencil_buffer (CoglPath  *path,
 | 
			
		||||
                                  gboolean   merge,
 | 
			
		||||
                                  gboolean   need_clear);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_cogl_path_get_bounds (CoglPath *path,
 | 
			
		||||
                       float *min_x,
 | 
			
		||||
                       float *min_y,
 | 
			
		||||
                       float *max_x,
 | 
			
		||||
                       float *max_y);
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
_cogl_path_is_rectangle (CoglPath *path);
 | 
			
		||||
 | 
			
		||||
#endif /* __COGL_PATH_PRIVATE_H */
 | 
			
		||||
@@ -1,86 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Cogl
 | 
			
		||||
 *
 | 
			
		||||
 * A Low Level GPU Graphics and Utilities API
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2008,2009,2013 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person
 | 
			
		||||
 * obtaining a copy of this software and associated documentation
 | 
			
		||||
 * files (the "Software"), to deal in the Software without
 | 
			
		||||
 * restriction, including without limitation the rights to use, copy,
 | 
			
		||||
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 | 
			
		||||
 * of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be
 | 
			
		||||
 * included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
			
		||||
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
			
		||||
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
			
		||||
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION)
 | 
			
		||||
#error "Only <cogl/cogl.h> can be included directly."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef __COGL_PATH_TYPES_H__
 | 
			
		||||
#define __COGL_PATH_TYPES_H__
 | 
			
		||||
 | 
			
		||||
#include <cogl/cogl-types.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
typedef struct _CoglPath CoglPath;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * CoglPathFillRule:
 | 
			
		||||
 * @COGL_PATH_FILL_RULE_NON_ZERO: Each time the line crosses an edge of
 | 
			
		||||
 * the path from left to right one is added to a counter and each time
 | 
			
		||||
 * it crosses from right to left the counter is decremented. If the
 | 
			
		||||
 * counter is non-zero then the point will be filled. See <xref
 | 
			
		||||
 * linkend="fill-rule-non-zero"/>.
 | 
			
		||||
 * @COGL_PATH_FILL_RULE_EVEN_ODD: If the line crosses an edge of the
 | 
			
		||||
 * path an odd number of times then the point will filled, otherwise
 | 
			
		||||
 * it won't. See <xref linkend="fill-rule-even-odd"/>.
 | 
			
		||||
 *
 | 
			
		||||
 * #CoglPathFillRule is used to determine how a path is filled. There
 | 
			
		||||
 * are two options - 'non-zero' and 'even-odd'. To work out whether any
 | 
			
		||||
 * point will be filled imagine drawing an infinetely long line in any
 | 
			
		||||
 * direction from that point. The number of times and the direction
 | 
			
		||||
 * that the edges of the path crosses this line determines whether the
 | 
			
		||||
 * line is filled as described below. Any open sub paths are treated
 | 
			
		||||
 * as if there was an extra line joining the first point and the last
 | 
			
		||||
 * point.
 | 
			
		||||
 *
 | 
			
		||||
 * The default fill rule when creating a path is %COGL_PATH_FILL_RULE_EVEN_ODD.
 | 
			
		||||
 *
 | 
			
		||||
 * <figure id="fill-rule-non-zero">
 | 
			
		||||
 *   <title>Example of filling various paths using the non-zero rule</title>
 | 
			
		||||
 *   <graphic fileref="fill-rule-non-zero.png" format="PNG"/>
 | 
			
		||||
 * </figure>
 | 
			
		||||
 *
 | 
			
		||||
 * <figure id="fill-rule-even-odd">
 | 
			
		||||
 *   <title>Example of filling various paths using the even-odd rule</title>
 | 
			
		||||
 *   <graphic fileref="fill-rule-even-odd.png" format="PNG"/>
 | 
			
		||||
 * </figure>
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
  COGL_PATH_FILL_RULE_NON_ZERO,
 | 
			
		||||
  COGL_PATH_FILL_RULE_EVEN_ODD
 | 
			
		||||
} CoglPathFillRule;
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __COGL_PATH_TYPES_H__ */
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,60 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Cogl
 | 
			
		||||
 *
 | 
			
		||||
 * A Low Level GPU Graphics and Utilities API
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2008,2009,2013 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person
 | 
			
		||||
 * obtaining a copy of this software and associated documentation
 | 
			
		||||
 * files (the "Software"), to deal in the Software without
 | 
			
		||||
 * restriction, including without limitation the rights to use, copy,
 | 
			
		||||
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 | 
			
		||||
 * of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be
 | 
			
		||||
 * included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
			
		||||
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
			
		||||
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
			
		||||
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __COGL_PATH_H__
 | 
			
		||||
#define __COGL_PATH_H__
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:cogl-paths
 | 
			
		||||
 * @short_description: Functions for constructing and drawing 2D paths.
 | 
			
		||||
 *
 | 
			
		||||
 * There are two levels on which drawing with cogl-paths can be used.
 | 
			
		||||
 * The highest level functions construct various simple primitive
 | 
			
		||||
 * shapes to be either filled or stroked. Using a lower-level set of
 | 
			
		||||
 * functions more complex and arbitrary paths can be constructed by
 | 
			
		||||
 * concatenating straight line, bezier curve and arc segments.
 | 
			
		||||
 *
 | 
			
		||||
 * When constructing arbitrary paths, the current pen location is
 | 
			
		||||
 * initialized using the move_to command. The subsequent path segments
 | 
			
		||||
 * implicitly use the last pen location as their first vertex and move
 | 
			
		||||
 * the pen location to the last vertex they produce at the end. Also
 | 
			
		||||
 * there are special versions of functions that allow specifying the
 | 
			
		||||
 * vertices of the path segments relative to the last pen location
 | 
			
		||||
 * rather then in the absolute coordinates.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <cogl/cogl-defines.h>
 | 
			
		||||
 | 
			
		||||
#include <cogl-path/cogl-path-enum-types.h>
 | 
			
		||||
#include <cogl-path/cogl-path-types.h>
 | 
			
		||||
#include <cogl-path/cogl-path-functions.h>
 | 
			
		||||
 | 
			
		||||
#endif /* __COGL_PATH_H__ */
 | 
			
		||||
 | 
			
		||||
@@ -1,59 +0,0 @@
 | 
			
		||||
/* cogl1-path-functions.h */
 | 
			
		||||
cogl_clip_push_from_path
 | 
			
		||||
cogl_clip_push_from_path_preserve
 | 
			
		||||
cogl_get_path
 | 
			
		||||
cogl_is_path
 | 
			
		||||
cogl_path_arc
 | 
			
		||||
cogl_path_close
 | 
			
		||||
cogl_path_copy
 | 
			
		||||
cogl_path_curve_to
 | 
			
		||||
cogl_path_ellipse
 | 
			
		||||
cogl_path_fill
 | 
			
		||||
cogl_path_fill_preserve
 | 
			
		||||
cogl_path_get_fill_rule
 | 
			
		||||
#ifdef COGL_HAS_GTYPE_SUPPORT
 | 
			
		||||
cogl_path_get_gtype
 | 
			
		||||
#endif
 | 
			
		||||
cogl_path_line
 | 
			
		||||
cogl_path_line_to
 | 
			
		||||
cogl_path_move_to
 | 
			
		||||
cogl_path_new
 | 
			
		||||
cogl_path_polygon
 | 
			
		||||
cogl_path_polyline
 | 
			
		||||
cogl_path_rectangle
 | 
			
		||||
cogl_path_rel_curve_to
 | 
			
		||||
cogl_path_rel_line_to
 | 
			
		||||
cogl_path_rel_move_to
 | 
			
		||||
cogl_path_round_rectangle
 | 
			
		||||
cogl_path_set_fill_rule
 | 
			
		||||
cogl_path_stroke
 | 
			
		||||
cogl_path_stroke_preserve
 | 
			
		||||
cogl_set_path
 | 
			
		||||
 | 
			
		||||
/* cogl2-path-functions.h */
 | 
			
		||||
cogl_framebuffer_fill_path
 | 
			
		||||
cogl_framebuffer_push_path_clip
 | 
			
		||||
cogl_framebuffer_stroke_path
 | 
			
		||||
cogl2_clip_push_from_path
 | 
			
		||||
cogl2_path_arc
 | 
			
		||||
cogl2_path_close
 | 
			
		||||
cogl2_path_curve_to
 | 
			
		||||
cogl2_path_ellipse
 | 
			
		||||
cogl2_path_fill
 | 
			
		||||
cogl2_path_get_fill_rule
 | 
			
		||||
cogl2_path_line
 | 
			
		||||
cogl2_path_line_to
 | 
			
		||||
cogl2_path_move_to
 | 
			
		||||
cogl2_path_new
 | 
			
		||||
cogl2_path_polygon
 | 
			
		||||
cogl2_path_polyline
 | 
			
		||||
cogl2_path_rectangle
 | 
			
		||||
cogl2_path_rel_curve_to
 | 
			
		||||
cogl2_path_rel_line_to
 | 
			
		||||
cogl2_path_rel_move_to
 | 
			
		||||
cogl2_path_round_rectangle
 | 
			
		||||
cogl2_path_set_fill_rule
 | 
			
		||||
cogl2_path_stroke
 | 
			
		||||
 | 
			
		||||
/* cogl-path-enums.h-contents may change as header is generated */
 | 
			
		||||
cogl_path_fill_rule_get_type
 | 
			
		||||
@@ -1,17 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
global:
 | 
			
		||||
  cogl_framebuffer_*;
 | 
			
		||||
  cogl_path_*;
 | 
			
		||||
  cogl_is_*;
 | 
			
		||||
  cogl_clip_*;
 | 
			
		||||
  cogl_get_*;
 | 
			
		||||
  cogl_set_*;
 | 
			
		||||
  cogl2_framebuffer_*;
 | 
			
		||||
  cogl2_path_*;
 | 
			
		||||
  cogl2_is_*;
 | 
			
		||||
  cogl2_clip_*;
 | 
			
		||||
  cogl2_get_*;
 | 
			
		||||
  cogl2_set_*;
 | 
			
		||||
local:
 | 
			
		||||
  *;
 | 
			
		||||
};
 | 
			
		||||
@@ -1,93 +0,0 @@
 | 
			
		||||
cogl_path_includesubdir = join_paths(cogl_includesubdir, 'cogl-path')
 | 
			
		||||
cogl_path_includedir = join_paths(cogl_includedir, 'cogl-path')
 | 
			
		||||
 | 
			
		||||
cogl_path_public_headers = [
 | 
			
		||||
  'cogl-path.h',
 | 
			
		||||
  'cogl-path-functions.h',
 | 
			
		||||
  'cogl-path-types.h',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
cogl_path_sources = [
 | 
			
		||||
  'cogl-path.c',
 | 
			
		||||
  'cogl-path-private.h',
 | 
			
		||||
  'tesselator/dict-list.h',
 | 
			
		||||
  'tesselator/dict.c',
 | 
			
		||||
  'tesselator/dict.h',
 | 
			
		||||
  'tesselator/geom.c',
 | 
			
		||||
  'tesselator/geom.h',
 | 
			
		||||
  'tesselator/gluos.h',
 | 
			
		||||
  'tesselator/memalloc.h',
 | 
			
		||||
  'tesselator/mesh.c',
 | 
			
		||||
  'tesselator/mesh.h',
 | 
			
		||||
  'tesselator/normal.c',
 | 
			
		||||
  'tesselator/normal.h',
 | 
			
		||||
  'tesselator/priorityq-heap.h',
 | 
			
		||||
  'tesselator/priorityq-sort.h',
 | 
			
		||||
  'tesselator/priorityq.c',
 | 
			
		||||
  'tesselator/priorityq.h',
 | 
			
		||||
  'tesselator/render.c',
 | 
			
		||||
  'tesselator/render.h',
 | 
			
		||||
  'tesselator/sweep.c',
 | 
			
		||||
  'tesselator/sweep.h',
 | 
			
		||||
  'tesselator/tess.c',
 | 
			
		||||
  'tesselator/tess.h',
 | 
			
		||||
  'tesselator/tesselator.h',
 | 
			
		||||
  'tesselator/tessmono.c',
 | 
			
		||||
  'tesselator/tessmono.h',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
cogl_path_includepath = include_directories('.')
 | 
			
		||||
 | 
			
		||||
libmutter_cogl_path_enum_types = gnome.mkenums('cogl-path-enum-types',
 | 
			
		||||
  sources: 'cogl-path-types.h',
 | 
			
		||||
  c_template: 'cogl-path-enum-types.c.in',
 | 
			
		||||
  h_template: 'cogl-path-enum-types.h.in',
 | 
			
		||||
  install_dir: cogl_path_includedir,
 | 
			
		||||
  install_header: true,
 | 
			
		||||
)
 | 
			
		||||
libmutter_cogl_path_enum_types_h = libmutter_cogl_path_enum_types[1]
 | 
			
		||||
 | 
			
		||||
cogl_path_sources += libmutter_cogl_path_enum_types
 | 
			
		||||
 | 
			
		||||
cogl_path_c_args = [
 | 
			
		||||
  cogl_c_args,
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
libmutter_cogl_path_map = 'libmutter-cogl-path.map'
 | 
			
		||||
libmutter_cogl_path_link_args = [
 | 
			
		||||
  '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(),
 | 
			
		||||
      libmutter_cogl_path_map),
 | 
			
		||||
]
 | 
			
		||||
libmutter_cogl_path = shared_library('mutter-cogl-path-' + libmutter_api_version,
 | 
			
		||||
  sources: [cogl_path_sources, cogl_path_public_headers],
 | 
			
		||||
  version: '0.0.0',
 | 
			
		||||
  soversion: 0,
 | 
			
		||||
  c_args: cogl_path_c_args,
 | 
			
		||||
  include_directories: [cogl_includepath, cogl_path_includepath],
 | 
			
		||||
  link_depends: libmutter_cogl_path_map,
 | 
			
		||||
  link_args: libmutter_cogl_path_link_args,
 | 
			
		||||
  dependencies: libmutter_cogl_dep,
 | 
			
		||||
  install_rpath: pkglibdir,
 | 
			
		||||
  install_dir: pkglibdir,
 | 
			
		||||
  install: true,
 | 
			
		||||
)
 | 
			
		||||
libmutter_cogl_path_dep = declare_dependency(
 | 
			
		||||
  sources: [libmutter_cogl_path_enum_types_h],
 | 
			
		||||
  link_with: libmutter_cogl_path
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
install_headers(cogl_path_public_headers,
 | 
			
		||||
  subdir: cogl_path_includesubdir)
 | 
			
		||||
 | 
			
		||||
pkg.generate(libmutter_cogl_path,
 | 
			
		||||
  name: 'CoglPath',
 | 
			
		||||
  filebase: 'mutter-cogl-path-' + libmutter_api_version,
 | 
			
		||||
  description: 'A 2D path drawing library for Cogl in mutter',
 | 
			
		||||
  subdirs: join_paths(pkgname, 'cogl'),
 | 
			
		||||
  requires: [cogl_pkg_deps, libmutter_cogl_name],
 | 
			
		||||
  version: meson.project_version(),
 | 
			
		||||
  variables: [
 | 
			
		||||
    'apiversion=' + libmutter_api_version,
 | 
			
		||||
  ],
 | 
			
		||||
  install_dir: pcdir,
 | 
			
		||||
)
 | 
			
		||||
@@ -1,13 +0,0 @@
 | 
			
		||||
prefix=@prefix@
 | 
			
		||||
exec_prefix=@exec_prefix@
 | 
			
		||||
apiversion=@LIBMUTTER_API_VERSION@
 | 
			
		||||
libdir=@libdir@/mutter-${apiversion}
 | 
			
		||||
includedir=@includedir@/mutter-${apiversion}
 | 
			
		||||
requires=@COGL_PKG_REQUIRES@ mutter-cogl-${apiversion}
 | 
			
		||||
 | 
			
		||||
Name: Cogl
 | 
			
		||||
Description: A 2D path drawing library for Cogl
 | 
			
		||||
Version: @MUTTER_VERSION@
 | 
			
		||||
Libs: -L${libdir} -lmutter-cogl-path-${apiversion}
 | 
			
		||||
Cflags: -I${includedir}/cogl
 | 
			
		||||
Requires: ${requires}
 | 
			
		||||
@@ -1,446 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
General Polygon Tesselation
 | 
			
		||||
---------------------------
 | 
			
		||||
 | 
			
		||||
  This note describes a tesselator for polygons consisting of one or
 | 
			
		||||
  more closed contours.  It is backward-compatible with the current
 | 
			
		||||
  OpenGL Utilities tesselator, and is intended to replace it.  Here is
 | 
			
		||||
  a summary of the major differences:
 | 
			
		||||
 | 
			
		||||
   - input contours can be intersecting, self-intersecting, or degenerate.
 | 
			
		||||
  
 | 
			
		||||
   - supports a choice of several winding rules for determining which parts
 | 
			
		||||
     of the polygon are on the "interior".  This makes it possible to do
 | 
			
		||||
     CSG operations on polygons.
 | 
			
		||||
  
 | 
			
		||||
   - boundary extraction: instead of tesselating the polygon, returns a
 | 
			
		||||
     set of closed contours which separate the interior from the exterior.
 | 
			
		||||
  
 | 
			
		||||
   - returns the output as a small number of triangle fans and strips,
 | 
			
		||||
     rather than a list of independent triangles (when possible).
 | 
			
		||||
  
 | 
			
		||||
   - output is available as an explicit mesh (a quad-edge structure),
 | 
			
		||||
     in addition to the normal callback interface.
 | 
			
		||||
  
 | 
			
		||||
   - the algorithm used is extremely robust.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
The interface
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
  The tesselator state is maintained in a "tesselator object".
 | 
			
		||||
  These are allocated and destroyed using
 | 
			
		||||
 | 
			
		||||
     GLUtesselator *gluNewTess( void );
 | 
			
		||||
     void gluDeleteTess( GLUtesselator *tess );
 | 
			
		||||
 | 
			
		||||
  Several tesselator objects may be used simultaneously.
 | 
			
		||||
 | 
			
		||||
  Inputs
 | 
			
		||||
  ------
 | 
			
		||||
  
 | 
			
		||||
  The input contours are specified with the following routines:
 | 
			
		||||
 | 
			
		||||
     void gluTessBeginPolygon( GLUtesselator *tess );
 | 
			
		||||
     void gluTessBeginContour( GLUtesselator *tess );
 | 
			
		||||
     void gluTessVertex( GLUtesselator *tess, GLUcoord coords[3], void *data );
 | 
			
		||||
     void gluTessEndContour( GLUtesselator *tess );
 | 
			
		||||
     void gluTessEndPolygon( GLUtesselator *tess );
 | 
			
		||||
 | 
			
		||||
  Within each BeginPolygon/EndPolygon pair, there can be zero or more
 | 
			
		||||
  calls to BeginContour/EndContour.  Within each contour, there are zero
 | 
			
		||||
  or more calls to gluTessVertex().  The vertices specify a closed
 | 
			
		||||
  contour (the last vertex of each contour is automatically linked to
 | 
			
		||||
  the first).
 | 
			
		||||
 | 
			
		||||
  "coords" give the coordinates of the vertex in 3-space.  For useful
 | 
			
		||||
  results, all vertices should lie in some plane, since the vertices
 | 
			
		||||
  are projected onto a plane before tesselation.  "data" is a pointer
 | 
			
		||||
  to a user-defined vertex structure, which typically contains other
 | 
			
		||||
  information such as color, texture coordinates, normal, etc.  It is
 | 
			
		||||
  used to refer to the vertex during rendering.
 | 
			
		||||
 | 
			
		||||
  The library can be compiled in single- or double-precision; the type
 | 
			
		||||
  GLUcoord represents either "float" or "double" accordingly.  The GLU
 | 
			
		||||
  version will be available in double-precision only.  Compile with
 | 
			
		||||
  GLU_TESS_API_FLOAT defined to get the single-precision version.
 | 
			
		||||
 | 
			
		||||
  When EndPolygon is called, the tesselation algorithm determines
 | 
			
		||||
  which regions are interior to the given contours, according to one
 | 
			
		||||
  of several "winding rules" described below.  The interior regions
 | 
			
		||||
  are then tesselated, and the output is provided as callbacks.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  Rendering Callbacks
 | 
			
		||||
  -------------------
 | 
			
		||||
 | 
			
		||||
  Callbacks are specified by the client using
 | 
			
		||||
 | 
			
		||||
     void gluTessCallback( GLUtesselator *tess, GLenum which, void (*fn)());
 | 
			
		||||
 | 
			
		||||
  If "fn" is NULL, any previously defined callback is discarded.
 | 
			
		||||
  
 | 
			
		||||
  The callbacks used to provide output are:	/* which == */
 | 
			
		||||
 | 
			
		||||
     void begin( GLenum type );			/* GLU_TESS_BEGIN */
 | 
			
		||||
     void edgeFlag( GLboolean flag );		/* GLU_TESS_EDGE_FLAG */
 | 
			
		||||
     void vertex( void *data );			/* GLU_TESS_VERTEX */
 | 
			
		||||
     void end( void );				/* GLU_TESS_END */
 | 
			
		||||
 | 
			
		||||
  Any of the callbacks may be left undefined; if so, the corresponding
 | 
			
		||||
  information will not be supplied during rendering.
 | 
			
		||||
 | 
			
		||||
  The "begin" callback indicates the start of a primitive; type is one
 | 
			
		||||
  of GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, or GL_TRIANGLES (but see the
 | 
			
		||||
  notes on "boundary extraction" below).
 | 
			
		||||
  
 | 
			
		||||
  It is followed by any number of "vertex" callbacks, which supply the
 | 
			
		||||
  vertices in the same order as expected by the corresponding glBegin()
 | 
			
		||||
  call.  After the last vertex of a given primitive, there is a callback
 | 
			
		||||
  to "end".
 | 
			
		||||
 | 
			
		||||
  If the "edgeFlag" callback is provided, no triangle fans or strips
 | 
			
		||||
  will be used.  When edgeFlag is called, if "flag" is GL_TRUE then each
 | 
			
		||||
  vertex which follows begins an edge which lies on the polygon boundary
 | 
			
		||||
  (ie. an edge which separates an interior region from an exterior one).
 | 
			
		||||
  If "flag" is GL_FALSE, each vertex which follows begins an edge which lies
 | 
			
		||||
  in the polygon interior.  "edgeFlag" will be called before the first
 | 
			
		||||
  call to "vertex".
 | 
			
		||||
 | 
			
		||||
  Other Callbacks
 | 
			
		||||
  ---------------
 | 
			
		||||
 | 
			
		||||
   void mesh( GLUmesh *mesh );			/* GLU_TESS_MESH */
 | 
			
		||||
 | 
			
		||||
   - Returns an explicit mesh, represented using the quad-edge structure
 | 
			
		||||
     (Guibas/Stolfi '85).  Other implementations of this interface might
 | 
			
		||||
     use a different mesh structure, so this is available only only as an
 | 
			
		||||
     SGI extension.  When the mesh is no longer needed, it should be freed
 | 
			
		||||
     using
 | 
			
		||||
 | 
			
		||||
	void gluDeleteMesh( GLUmesh *mesh );
 | 
			
		||||
 | 
			
		||||
     There is a brief description of this data structure in the include
 | 
			
		||||
     file "mesh.h".  For the full details, see L. Guibas and J. Stolfi,
 | 
			
		||||
     Primitives for the manipulation of general subdivisions and the
 | 
			
		||||
     computation of Voronoi diagrams, ACM Transactions on Graphics,
 | 
			
		||||
     4(2):74-123, April 1985.  For an introduction, see the course notes
 | 
			
		||||
     for CS348a, "Mathematical Foundations of Computer Graphics",
 | 
			
		||||
     available at the Stanford bookstore (and taught during the fall
 | 
			
		||||
     quarter).
 | 
			
		||||
 | 
			
		||||
   void error( GLenum errno );			/* GLU_TESS_ERROR */
 | 
			
		||||
 | 
			
		||||
   - errno is one of	GLU_TESS_MISSING_BEGIN_POLYGON,
 | 
			
		||||
			GLU_TESS_MISSING_END_POLYGON,
 | 
			
		||||
			GLU_TESS_MISSING_BEGIN_CONTOUR,
 | 
			
		||||
			GLU_TESS_MISSING_END_CONTOUR,
 | 
			
		||||
			GLU_TESS_COORD_TOO_LARGE,
 | 
			
		||||
			GLU_TESS_NEED_COMBINE_CALLBACK
 | 
			
		||||
 | 
			
		||||
     The first four are obvious.  The interface recovers from these
 | 
			
		||||
     errors by inserting the missing call(s).
 | 
			
		||||
  
 | 
			
		||||
     GLU_TESS_COORD_TOO_LARGE says that some vertex coordinate exceeded
 | 
			
		||||
     the predefined constant GLU_TESS_MAX_COORD in absolute value, and
 | 
			
		||||
     that the value has been clamped.  (Coordinate values must be small
 | 
			
		||||
     enough so that two can be multiplied together without overflow.)
 | 
			
		||||
 | 
			
		||||
     GLU_TESS_NEED_COMBINE_CALLBACK says that the algorithm detected an
 | 
			
		||||
     intersection between two edges in the input data, and the "combine"
 | 
			
		||||
     callback (below) was not provided.  No output will be generated.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
   void combine( GLUcoord coords[3], void *data[4],	/* GLU_TESS_COMBINE */
 | 
			
		||||
		 GLUcoord weight[4], void **outData );
 | 
			
		||||
 | 
			
		||||
   - When the algorithm detects an intersection, or wishes to merge
 | 
			
		||||
     features, it needs to create a new vertex.  The vertex is defined
 | 
			
		||||
     as a linear combination of up to 4 existing vertices, referenced
 | 
			
		||||
     by data[0..3].  The coefficients of the linear combination are
 | 
			
		||||
     given by weight[0..3]; these weights always sum to 1.0.  All vertex
 | 
			
		||||
     pointers are valid even when some of the weights are zero.
 | 
			
		||||
     "coords" gives the location of the new vertex.
 | 
			
		||||
 | 
			
		||||
     The user must allocate another vertex, interpolate parameters
 | 
			
		||||
     using "data" and "weights", and return the new vertex pointer in
 | 
			
		||||
     "outData".  This handle is supplied during rendering callbacks.
 | 
			
		||||
     For example, if the polygon lies in an arbitrary plane in 3-space,
 | 
			
		||||
     and we associate a color with each vertex, the combine callback might
 | 
			
		||||
     look like this:
 | 
			
		||||
    
 | 
			
		||||
     void myCombine( GLUcoord coords[3], VERTEX *d[4],
 | 
			
		||||
                     GLUcoord w[4], VERTEX **dataOut )
 | 
			
		||||
     {
 | 
			
		||||
        VERTEX *new = new_vertex();
 | 
			
		||||
       
 | 
			
		||||
        new->x = coords[0];
 | 
			
		||||
        new->y = coords[1];
 | 
			
		||||
        new->z = coords[2];
 | 
			
		||||
        new->r = w[0]*d[0]->r + w[1]*d[1]->r + w[2]*d[2]->r + w[3]*d[3]->r;
 | 
			
		||||
        new->g = w[0]*d[0]->g + w[1]*d[1]->g + w[2]*d[2]->g + w[3]*d[3]->g;
 | 
			
		||||
        new->b = w[0]*d[0]->b + w[1]*d[1]->b + w[2]*d[2]->b + w[3]*d[3]->b;
 | 
			
		||||
        new->a = w[0]*d[0]->a + w[1]*d[1]->a + w[2]*d[2]->a + w[3]*d[3]->a;
 | 
			
		||||
        *dataOut = new;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
     If the algorithm detects an intersection, then the "combine" callback
 | 
			
		||||
     must be defined, and must write a non-NULL pointer into "dataOut".
 | 
			
		||||
     Otherwise the GLU_TESS_NEED_COMBINE_CALLBACK error occurs, and no
 | 
			
		||||
     output is generated.  This is the only error that can occur during
 | 
			
		||||
     tesselation and rendering.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  Control over Tesselation
 | 
			
		||||
  ------------------------
 | 
			
		||||
  
 | 
			
		||||
   void gluTessProperty( GLUtesselator *tess, GLenum which, GLUcoord value );
 | 
			
		||||
 | 
			
		||||
   Properties defined:
 | 
			
		||||
 | 
			
		||||
    - GLU_TESS_WINDING_RULE.  Possible values:
 | 
			
		||||
 | 
			
		||||
	  GLU_TESS_WINDING_ODD
 | 
			
		||||
	  GLU_TESS_WINDING_NONZERO
 | 
			
		||||
	  GLU_TESS_WINDING_POSITIVE
 | 
			
		||||
	  GLU_TESS_WINDING_NEGATIVE
 | 
			
		||||
	  GLU_TESS_WINDING_ABS_GEQ_TWO
 | 
			
		||||
 | 
			
		||||
      The input contours parition the plane into regions.  A winding
 | 
			
		||||
      rule determines which of these regions are inside the polygon.
 | 
			
		||||
      
 | 
			
		||||
      For a single contour C, the winding number of a point x is simply
 | 
			
		||||
      the signed number of revolutions we make around x as we travel
 | 
			
		||||
      once around C (where CCW is positive).  When there are several
 | 
			
		||||
      contours, the individual winding numbers are summed.  This
 | 
			
		||||
      procedure associates a signed integer value with each point x in
 | 
			
		||||
      the plane.  Note that the winding number is the same for all
 | 
			
		||||
      points in a single region.
 | 
			
		||||
 | 
			
		||||
      The winding rule classifies a region as "inside" if its winding
 | 
			
		||||
      number belongs to the chosen category (odd, nonzero, positive,
 | 
			
		||||
      negative, or absolute value of at least two).  The current GLU
 | 
			
		||||
      tesselator implements the "odd" rule.  The "nonzero" rule is another
 | 
			
		||||
      common way to define the interior.  The other three rules are
 | 
			
		||||
      useful for polygon CSG operations (see below).
 | 
			
		||||
 | 
			
		||||
    - GLU_TESS_BOUNDARY_ONLY.  Values: TRUE (non-zero) or FALSE (zero).
 | 
			
		||||
 | 
			
		||||
      If TRUE, returns a set of closed contours which separate the
 | 
			
		||||
      polygon interior and exterior (rather than a tesselation).
 | 
			
		||||
      Exterior contours are oriented CCW with respect to the normal,
 | 
			
		||||
      interior contours are oriented CW.  The GLU_TESS_BEGIN callback
 | 
			
		||||
      uses the type GL_LINE_LOOP for each contour.
 | 
			
		||||
      
 | 
			
		||||
    - GLU_TESS_TOLERANCE.  Value: a real number between 0.0 and 1.0.
 | 
			
		||||
 | 
			
		||||
      This specifies a tolerance for merging features to reduce the size
 | 
			
		||||
      of the output.  For example, two vertices which are very close to
 | 
			
		||||
      each other might be replaced by a single vertex.  The tolerance
 | 
			
		||||
      is multiplied by the largest coordinate magnitude of any input vertex;
 | 
			
		||||
      this specifies the maximum distance that any feature can move as the
 | 
			
		||||
      result of a single merge operation.  If a single feature takes part
 | 
			
		||||
      in several merge operations, the total distance moved could be larger.
 | 
			
		||||
 | 
			
		||||
      Feature merging is completely optional; the tolerance is only a hint.
 | 
			
		||||
      The implementation is free to merge in some cases and not in others,
 | 
			
		||||
      or to never merge features at all.  The default tolerance is zero.
 | 
			
		||||
      
 | 
			
		||||
      The current implementation merges vertices only if they are exactly
 | 
			
		||||
      coincident, regardless of the current tolerance.  A vertex is
 | 
			
		||||
      spliced into an edge only if the implementation is unable to
 | 
			
		||||
      distinguish which side of the edge the vertex lies on.
 | 
			
		||||
      Two edges are merged only when both endpoints are identical.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
   void gluTessNormal( GLUtesselator *tess,
 | 
			
		||||
		      GLUcoord x, GLUcoord y, GLUcoord z )
 | 
			
		||||
 | 
			
		||||
    - Lets the user supply the polygon normal, if known.  All input data
 | 
			
		||||
      is projected into a plane perpendicular to the normal before
 | 
			
		||||
      tesselation.  All output triangles are oriented CCW with
 | 
			
		||||
      respect to the normal (CW orientation can be obtained by
 | 
			
		||||
      reversing the sign of the supplied normal).  For example, if
 | 
			
		||||
      you know that all polygons lie in the x-y plane, call
 | 
			
		||||
      "gluTessNormal(tess, 0.0, 0.0, 1.0)" before rendering any polygons.
 | 
			
		||||
      
 | 
			
		||||
    - If the supplied normal is (0,0,0) (the default value), the
 | 
			
		||||
      normal is determined as follows.  The direction of the normal,
 | 
			
		||||
      up to its sign, is found by fitting a plane to the vertices,
 | 
			
		||||
      without regard to how the vertices are connected.  It is
 | 
			
		||||
      expected that the input data lies approximately in plane;
 | 
			
		||||
      otherwise projection perpendicular to the computed normal may
 | 
			
		||||
      substantially change the geometry.  The sign of the normal is
 | 
			
		||||
      chosen so that the sum of the signed areas of all input contours
 | 
			
		||||
      is non-negative (where a CCW contour has positive area).
 | 
			
		||||
    
 | 
			
		||||
    - The supplied normal persists until it is changed by another
 | 
			
		||||
      call to gluTessNormal.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  Backward compatibility with the GLU tesselator
 | 
			
		||||
  ----------------------------------------------
 | 
			
		||||
 | 
			
		||||
  The preferred interface is the one described above.  The following
 | 
			
		||||
  routines are obsolete, and are provided only for backward compatibility:
 | 
			
		||||
 | 
			
		||||
    typedef GLUtesselator GLUtriangulatorObj;	/* obsolete name */
 | 
			
		||||
 | 
			
		||||
    void gluBeginPolygon( GLUtesselator *tess );
 | 
			
		||||
    void gluNextContour( GLUtesselator *tess, GLenum type );
 | 
			
		||||
    void gluEndPolygon( GLUtesselator *tess );
 | 
			
		||||
  
 | 
			
		||||
  "type" is one of GLU_EXTERIOR, GLU_INTERIOR, GLU_CCW, GLU_CW, or
 | 
			
		||||
  GLU_UNKNOWN.  It is ignored by the current GLU tesselator.
 | 
			
		||||
  
 | 
			
		||||
  GLU_BEGIN, GLU_VERTEX, GLU_END, GLU_ERROR, and GLU_EDGE_FLAG are defined
 | 
			
		||||
  as synonyms for GLU_TESS_BEGIN, GLU_TESS_VERTEX, GLU_TESS_END,
 | 
			
		||||
  GLU_TESS_ERROR, and GLU_TESS_EDGE_FLAG.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Polygon CSG operations
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
  The features of the tesselator make it easy to find the union, difference,
 | 
			
		||||
  or intersection of several polygons.
 | 
			
		||||
 | 
			
		||||
  First, assume that each polygon is defined so that the winding number
 | 
			
		||||
  is 0 for each exterior region, and 1 for each interior region.  Under
 | 
			
		||||
  this model, CCW contours define the outer boundary of the polygon, and
 | 
			
		||||
  CW contours define holes.  Contours may be nested, but a nested
 | 
			
		||||
  contour must be oriented oppositely from the contour that contains it.
 | 
			
		||||
 | 
			
		||||
  If the original polygons do not satisfy this description, they can be
 | 
			
		||||
  converted to this form by first running the tesselator with the
 | 
			
		||||
  GLU_TESS_BOUNDARY_ONLY property turned on.  This returns a list of
 | 
			
		||||
  contours satisfying the restriction above.  By allocating two
 | 
			
		||||
  tesselator objects, the callbacks from one tesselator can be fed
 | 
			
		||||
  directly to the input of another.
 | 
			
		||||
 | 
			
		||||
  Given two or more polygons of the form above, CSG operations can be
 | 
			
		||||
  implemented as follows:
 | 
			
		||||
 | 
			
		||||
  Union
 | 
			
		||||
     Draw all the input contours as a single polygon.  The winding number
 | 
			
		||||
     of each resulting region is the number of original polygons
 | 
			
		||||
     which cover it.  The union can be extracted using the
 | 
			
		||||
     GLU_TESS_WINDING_NONZERO or GLU_TESS_WINDING_POSITIVE winding rules.
 | 
			
		||||
     Note that with the nonzero rule, we would get the same result if
 | 
			
		||||
     all contour orientations were reversed.
 | 
			
		||||
 | 
			
		||||
  Intersection (two polygons at a time only)
 | 
			
		||||
     Draw a single polygon using the contours from both input polygons.
 | 
			
		||||
     Extract the result using GLU_TESS_WINDING_ABS_GEQ_TWO.  (Since this
 | 
			
		||||
     winding rule looks at the absolute value, reversing all contour
 | 
			
		||||
     orientations does not change the result.)
 | 
			
		||||
 | 
			
		||||
  Difference
 | 
			
		||||
  
 | 
			
		||||
     Suppose we want to compute A \ (B union C union D).  Draw a single
 | 
			
		||||
     polygon consisting of the unmodified contours from A, followed by
 | 
			
		||||
     the contours of B,C,D with the vertex order reversed (this changes
 | 
			
		||||
     the winding number of the interior regions to -1).  To extract the
 | 
			
		||||
     result, use the GLU_TESS_WINDING_POSITIVE rule.
 | 
			
		||||
   
 | 
			
		||||
     If B,C,D are the result of a GLU_TESS_BOUNDARY_ONLY call, an
 | 
			
		||||
     alternative to reversing the vertex order is to reverse the sign of
 | 
			
		||||
     the supplied normal.  For example in the x-y plane, call
 | 
			
		||||
     gluTessNormal( tess, 0.0, 0.0, -1.0 ).
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
Performance
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
  The tesselator is not intended for immediate-mode rendering; when
 | 
			
		||||
  possible the output should be cached in a user structure or display
 | 
			
		||||
  list.  General polygon tesselation is an inherently difficult problem,
 | 
			
		||||
  especially given the goal of extreme robustness.
 | 
			
		||||
 | 
			
		||||
  The implementation makes an effort to output a small number of fans
 | 
			
		||||
  and strips; this should improve the rendering performance when the
 | 
			
		||||
  output is used in a display list.
 | 
			
		||||
 | 
			
		||||
  Single-contour input polygons are first tested to see whether they can
 | 
			
		||||
  be rendered as a triangle fan with respect to the first vertex (to
 | 
			
		||||
  avoid running the full decomposition algorithm on convex polygons).
 | 
			
		||||
  Non-convex polygons may be rendered by this "fast path" as well, if
 | 
			
		||||
  the algorithm gets lucky in its choice of a starting vertex.
 | 
			
		||||
 | 
			
		||||
  For best performance follow these guidelines:
 | 
			
		||||
 | 
			
		||||
   - supply the polygon normal, if available, using gluTessNormal().
 | 
			
		||||
     This represents about 10% of the computation time.  For example,
 | 
			
		||||
     if all polygons lie in the x-y plane, use gluTessNormal(tess,0,0,1).
 | 
			
		||||
 | 
			
		||||
   - render many polygons using the same tesselator object, rather than
 | 
			
		||||
     allocating a new tesselator for each one.  (In a multi-threaded,
 | 
			
		||||
     multi-processor environment you may get better performance using
 | 
			
		||||
     several tesselators.)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Comparison with the GLU tesselator
 | 
			
		||||
----------------------------------
 | 
			
		||||
 | 
			
		||||
  On polygons which make it through the "fast path", the tesselator is
 | 
			
		||||
  3 to 5 times faster than the GLU tesselator.
 | 
			
		||||
 | 
			
		||||
  On polygons which don't make it through the fast path (but which don't
 | 
			
		||||
  have self-intersections or degeneracies), it is about 2 times slower.
 | 
			
		||||
 | 
			
		||||
  On polygons with self-intersections or degeneraces, there is nothing
 | 
			
		||||
  to compare against.
 | 
			
		||||
 | 
			
		||||
  The new tesselator generates many more fans and strips, reducing the
 | 
			
		||||
  number of vertices that need to be sent to the hardware.
 | 
			
		||||
 | 
			
		||||
  Key to the statistics:
 | 
			
		||||
 | 
			
		||||
	vert		number of input vertices on all contours
 | 
			
		||||
	cntr		number of input contours
 | 
			
		||||
	tri		number of triangles in all output primitives
 | 
			
		||||
	strip		number of triangle strips
 | 
			
		||||
	fan		number of triangle fans
 | 
			
		||||
	ind		number of independent triangles
 | 
			
		||||
	ms		number of milliseconds for tesselation
 | 
			
		||||
			(on a 150MHz R4400 Indy)
 | 
			
		||||
 | 
			
		||||
  Convex polygon examples:
 | 
			
		||||
 | 
			
		||||
New:     3 vert,   1 cntr,     1 tri,   0 strip,   0 fan,     1 ind,  0.0459 ms
 | 
			
		||||
Old:     3 vert,   1 cntr,     1 tri,   0 strip,   0 fan,     1 ind,   0.149 ms
 | 
			
		||||
New:     4 vert,   1 cntr,     2 tri,   0 strip,   1 fan,     0 ind,  0.0459 ms
 | 
			
		||||
Old:     4 vert,   1 cntr,     2 tri,   0 strip,   0 fan,     2 ind,   0.161 ms
 | 
			
		||||
New:    36 vert,   1 cntr,    34 tri,   0 strip,   1 fan,     0 ind,   0.153 ms
 | 
			
		||||
Old:    36 vert,   1 cntr,    34 tri,   0 strip,   0 fan,    34 ind,   0.621 ms
 | 
			
		||||
 | 
			
		||||
  Concave single-contour polygons:
 | 
			
		||||
 | 
			
		||||
New:     5 vert,   1 cntr,     3 tri,   0 strip,   1 fan,     0 ind,   0.052 ms
 | 
			
		||||
Old:     5 vert,   1 cntr,     3 tri,   0 strip,   0 fan,     3 ind,   0.252 ms
 | 
			
		||||
New:    19 vert,   1 cntr,    17 tri,   2 strip,   2 fan,     1 ind,   0.911 ms
 | 
			
		||||
Old:    19 vert,   1 cntr,    17 tri,   0 strip,   0 fan,    17 ind,   0.529 ms
 | 
			
		||||
New:   151 vert,   1 cntr,   149 tri,  13 strip,  18 fan,     3 ind,    6.82 ms
 | 
			
		||||
Old:   151 vert,   1 cntr,   149 tri,   0 strip,   3 fan,   143 ind,     2.7 ms
 | 
			
		||||
New:   574 vert,   1 cntr,   572 tri,  59 strip,  54 fan,    11 ind,    26.6 ms
 | 
			
		||||
Old:   574 vert,   1 cntr,   572 tri,   0 strip,  31 fan,   499 ind,    12.4 ms
 | 
			
		||||
 | 
			
		||||
  Multiple contours, but no intersections:
 | 
			
		||||
 | 
			
		||||
New:     7 vert,   2 cntr,     7 tri,   1 strip,   0 fan,     0 ind,   0.527 ms
 | 
			
		||||
Old:     7 vert,   2 cntr,     7 tri,   0 strip,   0 fan,     7 ind,   0.274 ms
 | 
			
		||||
New:    81 vert,   6 cntr,    89 tri,   9 strip,   7 fan,     6 ind,    3.88 ms
 | 
			
		||||
Old:    81 vert,   6 cntr,    89 tri,   0 strip,  13 fan,    61 ind,     2.2 ms
 | 
			
		||||
New:   391 vert,  19 cntr,   413 tri,  37 strip,  32 fan,    26 ind,    20.2 ms
 | 
			
		||||
Old:   391 vert,  19 cntr,   413 tri,   0 strip,  25 fan,   363 ind,    8.68 ms
 | 
			
		||||
 | 
			
		||||
  Self-intersecting and degenerate examples:
 | 
			
		||||
 | 
			
		||||
Bowtie:  4 vert,   1 cntr,     2 tri,   0 strip,   0 fan,     2 ind,   0.483 ms
 | 
			
		||||
Star:    5 vert,   1 cntr,     5 tri,   0 strip,   0 fan,     5 ind,    0.91 ms
 | 
			
		||||
Random: 24 vert,   7 cntr,    46 tri,   2 strip,  12 fan,     7 ind,    5.32 ms
 | 
			
		||||
Font:  333 vert,   2 cntr,   331 tri,  32 strip,  16 fan,     3 ind,    14.1 ms
 | 
			
		||||
:      167 vert,  35 cntr,   254 tri,   8 strip,  56 fan,    52 ind,    46.3 ms
 | 
			
		||||
:       78 vert,   1 cntr,  2675 tri, 148 strip, 207 fan,   180 ind,     243 ms
 | 
			
		||||
:    12480 vert,   2 cntr, 12478 tri, 736 strip,1275 fan,     5 ind,    1010 ms
 | 
			
		||||
@@ -1,100 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
** Author: Eric Veach, July 1994.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __dict_list_h_
 | 
			
		||||
#define __dict_list_h_
 | 
			
		||||
 | 
			
		||||
/* Use #define's so that another heap implementation can use this one */
 | 
			
		||||
 | 
			
		||||
#define DictKey		DictListKey
 | 
			
		||||
#define Dict		DictList
 | 
			
		||||
#define DictNode	DictListNode
 | 
			
		||||
 | 
			
		||||
#define dictNewDict(frame,leq)		__gl_dictListNewDict(frame,leq)
 | 
			
		||||
#define dictDeleteDict(dict)		__gl_dictListDeleteDict(dict)
 | 
			
		||||
 | 
			
		||||
#define dictSearch(dict,key)		__gl_dictListSearch(dict,key)
 | 
			
		||||
#define dictInsert(dict,key)		__gl_dictListInsert(dict,key)
 | 
			
		||||
#define dictInsertBefore(dict,node,key)	__gl_dictListInsertBefore(dict,node,key)
 | 
			
		||||
#define dictDelete(dict,node)		__gl_dictListDelete(dict,node)
 | 
			
		||||
 | 
			
		||||
#define dictKey(n)			__gl_dictListKey(n)
 | 
			
		||||
#define dictSucc(n)			__gl_dictListSucc(n)
 | 
			
		||||
#define dictPred(n)			__gl_dictListPred(n)
 | 
			
		||||
#define dictMin(d)			__gl_dictListMin(d)
 | 
			
		||||
#define dictMax(d)			__gl_dictListMax(d)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef void *DictKey;
 | 
			
		||||
typedef struct Dict Dict;
 | 
			
		||||
typedef struct DictNode DictNode;
 | 
			
		||||
 | 
			
		||||
Dict		*dictNewDict(
 | 
			
		||||
			void *frame,
 | 
			
		||||
			int (*leq)(void *frame, DictKey key1, DictKey key2) );
 | 
			
		||||
			
 | 
			
		||||
void		dictDeleteDict( Dict *dict );
 | 
			
		||||
 | 
			
		||||
/* Search returns the node with the smallest key greater than or equal
 | 
			
		||||
 * to the given key.  If there is no such key, returns a node whose
 | 
			
		||||
 * key is NULL.  Similarly, Succ(Max(d)) has a NULL key, etc.
 | 
			
		||||
 */
 | 
			
		||||
DictNode	*dictSearch( Dict *dict, DictKey key );
 | 
			
		||||
DictNode	*dictInsertBefore( Dict *dict, DictNode *node, DictKey key );
 | 
			
		||||
void		dictDelete( Dict *dict, DictNode *node );
 | 
			
		||||
 | 
			
		||||
#define		__gl_dictListKey(n)	((n)->key)
 | 
			
		||||
#define		__gl_dictListSucc(n)	((n)->next)
 | 
			
		||||
#define		__gl_dictListPred(n)	((n)->prev)
 | 
			
		||||
#define		__gl_dictListMin(d)	((d)->head.next)
 | 
			
		||||
#define		__gl_dictListMax(d)	((d)->head.prev)
 | 
			
		||||
#define	       __gl_dictListInsert(d,k) (dictInsertBefore((d),&(d)->head,(k)))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*** Private data structures ***/
 | 
			
		||||
 | 
			
		||||
struct DictNode {
 | 
			
		||||
  DictKey	key;
 | 
			
		||||
  DictNode	*next;
 | 
			
		||||
  DictNode	*prev;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Dict {
 | 
			
		||||
  DictNode	head;
 | 
			
		||||
  void		*frame;
 | 
			
		||||
  int		(*leq)(void *frame, DictKey key1, DictKey key2);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,111 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
** Author: Eric Veach, July 1994.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include "dict-list.h"
 | 
			
		||||
#include "memalloc.h"
 | 
			
		||||
 | 
			
		||||
/* really __gl_dictListNewDict */
 | 
			
		||||
Dict *dictNewDict( void *frame,
 | 
			
		||||
		   int (*leq)(void *frame, DictKey key1, DictKey key2) )
 | 
			
		||||
{
 | 
			
		||||
  Dict *dict = (Dict *) memAlloc( sizeof( Dict ));
 | 
			
		||||
  DictNode *head;
 | 
			
		||||
 | 
			
		||||
  if (dict == NULL) return NULL;
 | 
			
		||||
 | 
			
		||||
  head = &dict->head;
 | 
			
		||||
 | 
			
		||||
  head->key = NULL;
 | 
			
		||||
  head->next = head;
 | 
			
		||||
  head->prev = head;
 | 
			
		||||
 | 
			
		||||
  dict->frame = frame;
 | 
			
		||||
  dict->leq = leq;
 | 
			
		||||
 | 
			
		||||
  return dict;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* really __gl_dictListDeleteDict */
 | 
			
		||||
void dictDeleteDict( Dict *dict )
 | 
			
		||||
{
 | 
			
		||||
  DictNode *node, *next;
 | 
			
		||||
 | 
			
		||||
  for( node = dict->head.next; node != &dict->head; node = next ) {
 | 
			
		||||
    next = node->next;
 | 
			
		||||
    memFree( node );
 | 
			
		||||
  }
 | 
			
		||||
  memFree( dict );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* really __gl_dictListInsertBefore */
 | 
			
		||||
DictNode *dictInsertBefore( Dict *dict, DictNode *node, DictKey key )
 | 
			
		||||
{
 | 
			
		||||
  DictNode *newNode;
 | 
			
		||||
 | 
			
		||||
  do {
 | 
			
		||||
    node = node->prev;
 | 
			
		||||
  } while( node->key != NULL && ! (*dict->leq)(dict->frame, node->key, key));
 | 
			
		||||
 | 
			
		||||
  newNode = (DictNode *) memAlloc( sizeof( DictNode ));
 | 
			
		||||
  if (newNode == NULL) return NULL;
 | 
			
		||||
 | 
			
		||||
  newNode->key = key;
 | 
			
		||||
  newNode->next = node->next;
 | 
			
		||||
  node->next->prev = newNode;
 | 
			
		||||
  newNode->prev = node;
 | 
			
		||||
  node->next = newNode;
 | 
			
		||||
 | 
			
		||||
  return newNode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* really __gl_dictListDelete */
 | 
			
		||||
void dictDelete( Dict *dict, DictNode *node ) /*ARGSUSED*/
 | 
			
		||||
{
 | 
			
		||||
  node->next->prev = node->prev;
 | 
			
		||||
  node->prev->next = node->next;
 | 
			
		||||
  memFree( node );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* really __gl_dictListSearch */
 | 
			
		||||
DictNode *dictSearch( Dict *dict, DictKey key )
 | 
			
		||||
{
 | 
			
		||||
  DictNode *node = &dict->head;
 | 
			
		||||
 | 
			
		||||
  do {
 | 
			
		||||
    node = node->next;
 | 
			
		||||
  } while( node->key != NULL && ! (*dict->leq)(dict->frame, key, node->key));
 | 
			
		||||
 | 
			
		||||
  return node;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,100 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
** Author: Eric Veach, July 1994.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __dict_list_h_
 | 
			
		||||
#define __dict_list_h_
 | 
			
		||||
 | 
			
		||||
/* Use #define's so that another heap implementation can use this one */
 | 
			
		||||
 | 
			
		||||
#define DictKey		DictListKey
 | 
			
		||||
#define Dict		DictList
 | 
			
		||||
#define DictNode	DictListNode
 | 
			
		||||
 | 
			
		||||
#define dictNewDict(frame,leq)		__gl_dictListNewDict(frame,leq)
 | 
			
		||||
#define dictDeleteDict(dict)		__gl_dictListDeleteDict(dict)
 | 
			
		||||
 | 
			
		||||
#define dictSearch(dict,key)		__gl_dictListSearch(dict,key)
 | 
			
		||||
#define dictInsert(dict,key)		__gl_dictListInsert(dict,key)
 | 
			
		||||
#define dictInsertBefore(dict,node,key)	__gl_dictListInsertBefore(dict,node,key)
 | 
			
		||||
#define dictDelete(dict,node)		__gl_dictListDelete(dict,node)
 | 
			
		||||
 | 
			
		||||
#define dictKey(n)			__gl_dictListKey(n)
 | 
			
		||||
#define dictSucc(n)			__gl_dictListSucc(n)
 | 
			
		||||
#define dictPred(n)			__gl_dictListPred(n)
 | 
			
		||||
#define dictMin(d)			__gl_dictListMin(d)
 | 
			
		||||
#define dictMax(d)			__gl_dictListMax(d)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef void *DictKey;
 | 
			
		||||
typedef struct Dict Dict;
 | 
			
		||||
typedef struct DictNode DictNode;
 | 
			
		||||
 | 
			
		||||
Dict		*dictNewDict(
 | 
			
		||||
			void *frame,
 | 
			
		||||
			int (*leq)(void *frame, DictKey key1, DictKey key2) );
 | 
			
		||||
			
 | 
			
		||||
void		dictDeleteDict( Dict *dict );
 | 
			
		||||
 | 
			
		||||
/* Search returns the node with the smallest key greater than or equal
 | 
			
		||||
 * to the given key.  If there is no such key, returns a node whose
 | 
			
		||||
 * key is NULL.  Similarly, Succ(Max(d)) has a NULL key, etc.
 | 
			
		||||
 */
 | 
			
		||||
DictNode	*dictSearch( Dict *dict, DictKey key );
 | 
			
		||||
DictNode	*dictInsertBefore( Dict *dict, DictNode *node, DictKey key );
 | 
			
		||||
void		dictDelete( Dict *dict, DictNode *node );
 | 
			
		||||
 | 
			
		||||
#define		__gl_dictListKey(n)	((n)->key)
 | 
			
		||||
#define		__gl_dictListSucc(n)	((n)->next)
 | 
			
		||||
#define		__gl_dictListPred(n)	((n)->prev)
 | 
			
		||||
#define		__gl_dictListMin(d)	((d)->head.next)
 | 
			
		||||
#define		__gl_dictListMax(d)	((d)->head.prev)
 | 
			
		||||
#define	       __gl_dictListInsert(d,k) (dictInsertBefore((d),&(d)->head,(k)))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*** Private data structures ***/
 | 
			
		||||
 | 
			
		||||
struct DictNode {
 | 
			
		||||
  DictKey	key;
 | 
			
		||||
  DictNode	*next;
 | 
			
		||||
  DictNode	*prev;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Dict {
 | 
			
		||||
  DictNode	head;
 | 
			
		||||
  void		*frame;
 | 
			
		||||
  int		(*leq)(void *frame, DictKey key1, DictKey key2);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,264 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
** Author: Eric Veach, July 1994.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "gluos.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include "mesh.h"
 | 
			
		||||
#include "geom.h"
 | 
			
		||||
 | 
			
		||||
int __gl_vertLeq( GLUvertex *u, GLUvertex *v )
 | 
			
		||||
{
 | 
			
		||||
  /* Returns TRUE if u is lexicographically <= v. */
 | 
			
		||||
 | 
			
		||||
  return VertLeq( u, v );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLdouble __gl_edgeEval( GLUvertex *u, GLUvertex *v, GLUvertex *w )
 | 
			
		||||
{
 | 
			
		||||
  /* Given three vertices u,v,w such that VertLeq(u,v) && VertLeq(v,w),
 | 
			
		||||
   * evaluates the t-coord of the edge uw at the s-coord of the vertex v.
 | 
			
		||||
   * Returns v->t - (uw)(v->s), ie. the signed distance from uw to v.
 | 
			
		||||
   * If uw is vertical (and thus passes thru v), the result is zero.
 | 
			
		||||
   *
 | 
			
		||||
   * The calculation is extremely accurate and stable, even when v
 | 
			
		||||
   * is very close to u or w.  In particular if we set v->t = 0 and
 | 
			
		||||
   * let r be the negated result (this evaluates (uw)(v->s)), then
 | 
			
		||||
   * r is guaranteed to satisfy MIN(u->t,w->t) <= r <= MAX(u->t,w->t).
 | 
			
		||||
   */
 | 
			
		||||
  GLdouble gapL, gapR;
 | 
			
		||||
 | 
			
		||||
  assert( VertLeq( u, v ) && VertLeq( v, w ));
 | 
			
		||||
  
 | 
			
		||||
  gapL = v->s - u->s;
 | 
			
		||||
  gapR = w->s - v->s;
 | 
			
		||||
 | 
			
		||||
  if( gapL + gapR > 0 ) {
 | 
			
		||||
    if( gapL < gapR ) {
 | 
			
		||||
      return (v->t - u->t) + (u->t - w->t) * (gapL / (gapL + gapR));
 | 
			
		||||
    } else {
 | 
			
		||||
      return (v->t - w->t) + (w->t - u->t) * (gapR / (gapL + gapR));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  /* vertical line */
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLdouble __gl_edgeSign( GLUvertex *u, GLUvertex *v, GLUvertex *w )
 | 
			
		||||
{
 | 
			
		||||
  /* Returns a number whose sign matches EdgeEval(u,v,w) but which
 | 
			
		||||
   * is cheaper to evaluate.  Returns > 0, == 0 , or < 0
 | 
			
		||||
   * as v is above, on, or below the edge uw.
 | 
			
		||||
   */
 | 
			
		||||
  GLdouble gapL, gapR;
 | 
			
		||||
 | 
			
		||||
  assert( VertLeq( u, v ) && VertLeq( v, w ));
 | 
			
		||||
  
 | 
			
		||||
  gapL = v->s - u->s;
 | 
			
		||||
  gapR = w->s - v->s;
 | 
			
		||||
 | 
			
		||||
  if( gapL + gapR > 0 ) {
 | 
			
		||||
    return (v->t - w->t) * gapL + (v->t - u->t) * gapR;
 | 
			
		||||
  }
 | 
			
		||||
  /* vertical line */
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/***********************************************************************
 | 
			
		||||
 * Define versions of EdgeSign, EdgeEval with s and t transposed.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
GLdouble __gl_transEval( GLUvertex *u, GLUvertex *v, GLUvertex *w )
 | 
			
		||||
{
 | 
			
		||||
  /* Given three vertices u,v,w such that TransLeq(u,v) && TransLeq(v,w),
 | 
			
		||||
   * evaluates the t-coord of the edge uw at the s-coord of the vertex v.
 | 
			
		||||
   * Returns v->s - (uw)(v->t), ie. the signed distance from uw to v.
 | 
			
		||||
   * If uw is vertical (and thus passes thru v), the result is zero.
 | 
			
		||||
   *
 | 
			
		||||
   * The calculation is extremely accurate and stable, even when v
 | 
			
		||||
   * is very close to u or w.  In particular if we set v->s = 0 and
 | 
			
		||||
   * let r be the negated result (this evaluates (uw)(v->t)), then
 | 
			
		||||
   * r is guaranteed to satisfy MIN(u->s,w->s) <= r <= MAX(u->s,w->s).
 | 
			
		||||
   */
 | 
			
		||||
  GLdouble gapL, gapR;
 | 
			
		||||
 | 
			
		||||
  assert( TransLeq( u, v ) && TransLeq( v, w ));
 | 
			
		||||
  
 | 
			
		||||
  gapL = v->t - u->t;
 | 
			
		||||
  gapR = w->t - v->t;
 | 
			
		||||
 | 
			
		||||
  if( gapL + gapR > 0 ) {
 | 
			
		||||
    if( gapL < gapR ) {
 | 
			
		||||
      return (v->s - u->s) + (u->s - w->s) * (gapL / (gapL + gapR));
 | 
			
		||||
    } else {
 | 
			
		||||
      return (v->s - w->s) + (w->s - u->s) * (gapR / (gapL + gapR));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  /* vertical line */
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLdouble __gl_transSign( GLUvertex *u, GLUvertex *v, GLUvertex *w )
 | 
			
		||||
{
 | 
			
		||||
  /* Returns a number whose sign matches TransEval(u,v,w) but which
 | 
			
		||||
   * is cheaper to evaluate.  Returns > 0, == 0 , or < 0
 | 
			
		||||
   * as v is above, on, or below the edge uw.
 | 
			
		||||
   */
 | 
			
		||||
  GLdouble gapL, gapR;
 | 
			
		||||
 | 
			
		||||
  assert( TransLeq( u, v ) && TransLeq( v, w ));
 | 
			
		||||
  
 | 
			
		||||
  gapL = v->t - u->t;
 | 
			
		||||
  gapR = w->t - v->t;
 | 
			
		||||
 | 
			
		||||
  if( gapL + gapR > 0 ) {
 | 
			
		||||
    return (v->s - w->s) * gapL + (v->s - u->s) * gapR;
 | 
			
		||||
  }
 | 
			
		||||
  /* vertical line */
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int __gl_vertCCW( GLUvertex *u, GLUvertex *v, GLUvertex *w )
 | 
			
		||||
{
 | 
			
		||||
  /* For almost-degenerate situations, the results are not reliable.
 | 
			
		||||
   * Unless the floating-point arithmetic can be performed without
 | 
			
		||||
   * rounding errors, *any* implementation will give incorrect results
 | 
			
		||||
   * on some degenerate inputs, so the client must have some way to
 | 
			
		||||
   * handle this situation.
 | 
			
		||||
   */
 | 
			
		||||
  return (u->s*(v->t - w->t) + v->s*(w->t - u->t) + w->s*(u->t - v->t)) >= 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Given parameters a,x,b,y returns the value (b*x+a*y)/(a+b),
 | 
			
		||||
 * or (x+y)/2 if a==b==0.  It requires that a,b >= 0, and enforces
 | 
			
		||||
 * this in the rare case that one argument is slightly negative.
 | 
			
		||||
 * The implementation is extremely stable numerically.
 | 
			
		||||
 * In particular it guarantees that the result r satisfies
 | 
			
		||||
 * MIN(x,y) <= r <= MAX(x,y), and the results are very accurate
 | 
			
		||||
 * even when a and b differ greatly in magnitude.
 | 
			
		||||
 */
 | 
			
		||||
#define RealInterpolate(a,x,b,y)			\
 | 
			
		||||
  (a = (a < 0) ? 0 : a, b = (b < 0) ? 0 : b,		\
 | 
			
		||||
  ((a <= b) ? ((b == 0) ? ((x+y) / 2)			\
 | 
			
		||||
                        : (x + (y-x) * (a/(a+b))))	\
 | 
			
		||||
            : (y + (x-y) * (b/(a+b)))))
 | 
			
		||||
 | 
			
		||||
#ifndef FOR_TRITE_TEST_PROGRAM
 | 
			
		||||
#define Interpolate(a,x,b,y)	RealInterpolate(a,x,b,y)
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
/* Claim: the ONLY property the sweep algorithm relies on is that
 | 
			
		||||
 * MIN(x,y) <= r <= MAX(x,y).  This is a nasty way to test that.
 | 
			
		||||
 */
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
extern int RandomInterpolate;
 | 
			
		||||
 | 
			
		||||
GLdouble Interpolate( GLdouble a, GLdouble x, GLdouble b, GLdouble y)
 | 
			
		||||
{
 | 
			
		||||
printf("*********************%d\n",RandomInterpolate);
 | 
			
		||||
  if( RandomInterpolate ) {
 | 
			
		||||
    a = 1.2 * drand48() - 0.1;
 | 
			
		||||
    a = (a < 0) ? 0 : ((a > 1) ? 1 : a);
 | 
			
		||||
    b = 1.0 - a;
 | 
			
		||||
  }
 | 
			
		||||
  return RealInterpolate(a,x,b,y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define Swap(a,b)	do { GLUvertex *t = a; a = b; b = t; } while (0)
 | 
			
		||||
 | 
			
		||||
void __gl_edgeIntersect( GLUvertex *o1, GLUvertex *d1,
 | 
			
		||||
			 GLUvertex *o2, GLUvertex *d2,
 | 
			
		||||
			 GLUvertex *v )
 | 
			
		||||
/* Given edges (o1,d1) and (o2,d2), compute their point of intersection.
 | 
			
		||||
 * The computed point is guaranteed to lie in the intersection of the
 | 
			
		||||
 * bounding rectangles defined by each edge.
 | 
			
		||||
 */
 | 
			
		||||
{
 | 
			
		||||
  GLdouble z1, z2;
 | 
			
		||||
 | 
			
		||||
  /* This is certainly not the most efficient way to find the intersection
 | 
			
		||||
   * of two line segments, but it is very numerically stable.
 | 
			
		||||
   *
 | 
			
		||||
   * Strategy: find the two middle vertices in the VertLeq ordering,
 | 
			
		||||
   * and interpolate the intersection s-value from these.  Then repeat
 | 
			
		||||
   * using the TransLeq ordering to find the intersection t-value.
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  if( ! VertLeq( o1, d1 )) { Swap( o1, d1 ); }
 | 
			
		||||
  if( ! VertLeq( o2, d2 )) { Swap( o2, d2 ); }
 | 
			
		||||
  if( ! VertLeq( o1, o2 )) { Swap( o1, o2 ); Swap( d1, d2 ); }
 | 
			
		||||
 | 
			
		||||
  if( ! VertLeq( o2, d1 )) {
 | 
			
		||||
    /* Technically, no intersection -- do our best */
 | 
			
		||||
    v->s = (o2->s + d1->s) / 2;
 | 
			
		||||
  } else if( VertLeq( d1, d2 )) {
 | 
			
		||||
    /* Interpolate between o2 and d1 */
 | 
			
		||||
    z1 = EdgeEval( o1, o2, d1 );
 | 
			
		||||
    z2 = EdgeEval( o2, d1, d2 );
 | 
			
		||||
    if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; }
 | 
			
		||||
    v->s = Interpolate( z1, o2->s, z2, d1->s );
 | 
			
		||||
  } else {
 | 
			
		||||
    /* Interpolate between o2 and d2 */
 | 
			
		||||
    z1 = EdgeSign( o1, o2, d1 );
 | 
			
		||||
    z2 = -EdgeSign( o1, d2, d1 );
 | 
			
		||||
    if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; }
 | 
			
		||||
    v->s = Interpolate( z1, o2->s, z2, d2->s );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Now repeat the process for t */
 | 
			
		||||
 | 
			
		||||
  if( ! TransLeq( o1, d1 )) { Swap( o1, d1 ); }
 | 
			
		||||
  if( ! TransLeq( o2, d2 )) { Swap( o2, d2 ); }
 | 
			
		||||
  if( ! TransLeq( o1, o2 )) { Swap( o1, o2 ); Swap( d1, d2 ); }
 | 
			
		||||
 | 
			
		||||
  if( ! TransLeq( o2, d1 )) {
 | 
			
		||||
    /* Technically, no intersection -- do our best */
 | 
			
		||||
    v->t = (o2->t + d1->t) / 2;
 | 
			
		||||
  } else if( TransLeq( d1, d2 )) {
 | 
			
		||||
    /* Interpolate between o2 and d1 */
 | 
			
		||||
    z1 = TransEval( o1, o2, d1 );
 | 
			
		||||
    z2 = TransEval( o2, d1, d2 );
 | 
			
		||||
    if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; }
 | 
			
		||||
    v->t = Interpolate( z1, o2->t, z2, d1->t );
 | 
			
		||||
  } else {
 | 
			
		||||
    /* Interpolate between o2 and d2 */
 | 
			
		||||
    z1 = TransSign( o1, o2, d1 );
 | 
			
		||||
    z2 = -TransSign( o1, d2, d1 );
 | 
			
		||||
    if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; }
 | 
			
		||||
    v->t = Interpolate( z1, o2->t, z2, d2->t );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,84 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
** Author: Eric Veach, July 1994.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __geom_h_
 | 
			
		||||
#define __geom_h_
 | 
			
		||||
 | 
			
		||||
#include "mesh.h"
 | 
			
		||||
 | 
			
		||||
#ifdef NO_BRANCH_CONDITIONS
 | 
			
		||||
/* MIPS architecture has special instructions to evaluate boolean
 | 
			
		||||
 * conditions -- more efficient than branching, IF you can get the
 | 
			
		||||
 * compiler to generate the right instructions (SGI compiler doesn't)
 | 
			
		||||
 */
 | 
			
		||||
#define VertEq(u,v)	(((u)->s == (v)->s) & ((u)->t == (v)->t))
 | 
			
		||||
#define VertLeq(u,v)	(((u)->s < (v)->s) | \
 | 
			
		||||
                         ((u)->s == (v)->s & (u)->t <= (v)->t))
 | 
			
		||||
#else
 | 
			
		||||
#define VertEq(u,v)	((u)->s == (v)->s && (u)->t == (v)->t)
 | 
			
		||||
#define VertLeq(u,v)	(((u)->s < (v)->s) || \
 | 
			
		||||
                         ((u)->s == (v)->s && (u)->t <= (v)->t))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define EdgeEval(u,v,w) __gl_edgeEval(u,v,w)
 | 
			
		||||
#define EdgeSign(u,v,w) __gl_edgeSign(u,v,w)
 | 
			
		||||
 | 
			
		||||
/* Versions of VertLeq, EdgeSign, EdgeEval with s and t transposed. */
 | 
			
		||||
 | 
			
		||||
#define TransLeq(u,v)	(((u)->t < (v)->t) || \
 | 
			
		||||
                         ((u)->t == (v)->t && (u)->s <= (v)->s))
 | 
			
		||||
#define TransEval(u,v,w)	__gl_transEval(u,v,w)
 | 
			
		||||
#define TransSign(u,v,w)	__gl_transSign(u,v,w)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define EdgeGoesLeft(e) 	VertLeq( (e)->Dst, (e)->Org )
 | 
			
		||||
#define EdgeGoesRight(e)	VertLeq( (e)->Org, (e)->Dst )
 | 
			
		||||
 | 
			
		||||
#undef	ABS
 | 
			
		||||
#define ABS(x)	((x) < 0 ? -(x) : (x))
 | 
			
		||||
#define VertL1dist(u,v) (ABS(u->s - v->s) + ABS(u->t - v->t))
 | 
			
		||||
 | 
			
		||||
#define VertCCW(u,v,w)	__gl_vertCCW(u,v,w)
 | 
			
		||||
 | 
			
		||||
int		__gl_vertLeq( GLUvertex *u, GLUvertex *v );
 | 
			
		||||
GLdouble	__gl_edgeEval( GLUvertex *u, GLUvertex *v, GLUvertex *w );
 | 
			
		||||
GLdouble	__gl_edgeSign( GLUvertex *u, GLUvertex *v, GLUvertex *w );
 | 
			
		||||
GLdouble	__gl_transEval( GLUvertex *u, GLUvertex *v, GLUvertex *w );
 | 
			
		||||
GLdouble	__gl_transSign( GLUvertex *u, GLUvertex *v, GLUvertex *w );
 | 
			
		||||
int		__gl_vertCCW( GLUvertex *u, GLUvertex *v, GLUvertex *w );
 | 
			
		||||
void		__gl_edgeIntersect( GLUvertex *o1, GLUvertex *d1,
 | 
			
		||||
				    GLUvertex *o2, GLUvertex *d2,
 | 
			
		||||
				    GLUvertex *v );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1 +0,0 @@
 | 
			
		||||
/* This is a stub header to avoid having to change tess.c */
 | 
			
		||||
@@ -1,49 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Cogl
 | 
			
		||||
 *
 | 
			
		||||
 * A Low Level GPU Graphics and Utilities API
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2010 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person
 | 
			
		||||
 * obtaining a copy of this software and associated documentation
 | 
			
		||||
 * files (the "Software"), to deal in the Software without
 | 
			
		||||
 * restriction, including without limitation the rights to use, copy,
 | 
			
		||||
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 | 
			
		||||
 * of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be
 | 
			
		||||
 * included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
			
		||||
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
			
		||||
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
			
		||||
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* This is a simple replacement for memalloc from the SGI tesselator
 | 
			
		||||
   code to force it to use glib's allocation instead */
 | 
			
		||||
 | 
			
		||||
#ifndef __MEMALLOC_H__
 | 
			
		||||
#define __MEMALLOC_H__
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
#define memRealloc g_realloc
 | 
			
		||||
#define memAlloc   g_malloc
 | 
			
		||||
#define memFree    g_free
 | 
			
		||||
#define memInit(x) 1
 | 
			
		||||
 | 
			
		||||
/* tess.c defines TRUE and FALSE itself unconditionally so we need to
 | 
			
		||||
   undefine it from the glib headers */
 | 
			
		||||
#undef TRUE
 | 
			
		||||
#undef FALSE
 | 
			
		||||
 | 
			
		||||
#endif /* __MEMALLOC_H__ */
 | 
			
		||||
@@ -1,798 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
** Author: Eric Veach, July 1994.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "gluos.h"
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include "mesh.h"
 | 
			
		||||
#include "memalloc.h"
 | 
			
		||||
 | 
			
		||||
#ifndef TRUE
 | 
			
		||||
#define TRUE 1
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef FALSE
 | 
			
		||||
#define FALSE 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static GLUvertex *allocVertex(void)
 | 
			
		||||
{
 | 
			
		||||
   return (GLUvertex *)memAlloc( sizeof( GLUvertex ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GLUface *allocFace(void)
 | 
			
		||||
{
 | 
			
		||||
   return (GLUface *)memAlloc( sizeof( GLUface ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/************************ Utility Routines ************************/
 | 
			
		||||
 | 
			
		||||
/* Allocate and free half-edges in pairs for efficiency.
 | 
			
		||||
 * The *only* place that should use this fact is allocation/free.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct { GLUhalfEdge e, eSym; } EdgePair;
 | 
			
		||||
 | 
			
		||||
/* MakeEdge creates a new pair of half-edges which form their own loop.
 | 
			
		||||
 * No vertex or face structures are allocated, but these must be assigned
 | 
			
		||||
 * before the current edge operation is completed.
 | 
			
		||||
 */
 | 
			
		||||
static GLUhalfEdge *MakeEdge( GLUhalfEdge *eNext )
 | 
			
		||||
{
 | 
			
		||||
  GLUhalfEdge *e;
 | 
			
		||||
  GLUhalfEdge *eSym;
 | 
			
		||||
  GLUhalfEdge *ePrev;
 | 
			
		||||
  EdgePair *pair = (EdgePair *)memAlloc( sizeof( EdgePair ));
 | 
			
		||||
  if (pair == NULL) return NULL;
 | 
			
		||||
 | 
			
		||||
  e = &pair->e;
 | 
			
		||||
  eSym = &pair->eSym;
 | 
			
		||||
 | 
			
		||||
  /* Make sure eNext points to the first edge of the edge pair */
 | 
			
		||||
  if( eNext->Sym < eNext ) { eNext = eNext->Sym; }
 | 
			
		||||
 | 
			
		||||
  /* Insert in circular doubly-linked list before eNext.
 | 
			
		||||
   * Note that the prev pointer is stored in Sym->next.
 | 
			
		||||
   */
 | 
			
		||||
  ePrev = eNext->Sym->next;
 | 
			
		||||
  eSym->next = ePrev;
 | 
			
		||||
  ePrev->Sym->next = e;
 | 
			
		||||
  e->next = eNext;
 | 
			
		||||
  eNext->Sym->next = eSym;
 | 
			
		||||
 | 
			
		||||
  e->Sym = eSym;
 | 
			
		||||
  e->Onext = e;
 | 
			
		||||
  e->Lnext = eSym;
 | 
			
		||||
  e->Org = NULL;
 | 
			
		||||
  e->Lface = NULL;
 | 
			
		||||
  e->winding = 0;
 | 
			
		||||
  e->activeRegion = NULL;
 | 
			
		||||
 | 
			
		||||
  eSym->Sym = e;
 | 
			
		||||
  eSym->Onext = eSym;
 | 
			
		||||
  eSym->Lnext = e;
 | 
			
		||||
  eSym->Org = NULL;
 | 
			
		||||
  eSym->Lface = NULL;
 | 
			
		||||
  eSym->winding = 0;
 | 
			
		||||
  eSym->activeRegion = NULL;
 | 
			
		||||
 | 
			
		||||
  return e;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Splice( a, b ) is best described by the Guibas/Stolfi paper or the
 | 
			
		||||
 * CS348a notes (see mesh.h).  Basically it modifies the mesh so that
 | 
			
		||||
 * a->Onext and b->Onext are exchanged.  This can have various effects
 | 
			
		||||
 * depending on whether a and b belong to different face or vertex rings.
 | 
			
		||||
 * For more explanation see __gl_meshSplice() below.
 | 
			
		||||
 */
 | 
			
		||||
static void Splice( GLUhalfEdge *a, GLUhalfEdge *b )
 | 
			
		||||
{
 | 
			
		||||
  GLUhalfEdge *aOnext = a->Onext;
 | 
			
		||||
  GLUhalfEdge *bOnext = b->Onext;
 | 
			
		||||
 | 
			
		||||
  aOnext->Sym->Lnext = b;
 | 
			
		||||
  bOnext->Sym->Lnext = a;
 | 
			
		||||
  a->Onext = bOnext;
 | 
			
		||||
  b->Onext = aOnext;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* MakeVertex( newVertex, eOrig, vNext ) attaches a new vertex and makes it the
 | 
			
		||||
 * origin of all edges in the vertex loop to which eOrig belongs. "vNext" gives
 | 
			
		||||
 * a place to insert the new vertex in the global vertex list.  We insert
 | 
			
		||||
 * the new vertex *before* vNext so that algorithms which walk the vertex
 | 
			
		||||
 * list will not see the newly created vertices.
 | 
			
		||||
 */
 | 
			
		||||
static void MakeVertex( GLUvertex *newVertex, 
 | 
			
		||||
			GLUhalfEdge *eOrig, GLUvertex *vNext )
 | 
			
		||||
{
 | 
			
		||||
  GLUhalfEdge *e;
 | 
			
		||||
  GLUvertex *vPrev;
 | 
			
		||||
  GLUvertex *vNew = newVertex;
 | 
			
		||||
 | 
			
		||||
  assert(vNew != NULL);
 | 
			
		||||
 | 
			
		||||
  /* insert in circular doubly-linked list before vNext */
 | 
			
		||||
  vPrev = vNext->prev;
 | 
			
		||||
  vNew->prev = vPrev;
 | 
			
		||||
  vPrev->next = vNew;
 | 
			
		||||
  vNew->next = vNext;
 | 
			
		||||
  vNext->prev = vNew;
 | 
			
		||||
 | 
			
		||||
  vNew->anEdge = eOrig;
 | 
			
		||||
  vNew->data = NULL;
 | 
			
		||||
  /* leave coords, s, t undefined */
 | 
			
		||||
 | 
			
		||||
  /* fix other edges on this vertex loop */
 | 
			
		||||
  e = eOrig;
 | 
			
		||||
  do {
 | 
			
		||||
    e->Org = vNew;
 | 
			
		||||
    e = e->Onext;
 | 
			
		||||
  } while( e != eOrig );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* MakeFace( newFace, eOrig, fNext ) attaches a new face and makes it the left
 | 
			
		||||
 * face of all edges in the face loop to which eOrig belongs.  "fNext" gives
 | 
			
		||||
 * a place to insert the new face in the global face list.  We insert
 | 
			
		||||
 * the new face *before* fNext so that algorithms which walk the face
 | 
			
		||||
 * list will not see the newly created faces.
 | 
			
		||||
 */
 | 
			
		||||
static void MakeFace( GLUface *newFace, GLUhalfEdge *eOrig, GLUface *fNext )
 | 
			
		||||
{
 | 
			
		||||
  GLUhalfEdge *e;
 | 
			
		||||
  GLUface *fPrev;
 | 
			
		||||
  GLUface *fNew = newFace;
 | 
			
		||||
 | 
			
		||||
  assert(fNew != NULL); 
 | 
			
		||||
 | 
			
		||||
  /* insert in circular doubly-linked list before fNext */
 | 
			
		||||
  fPrev = fNext->prev;
 | 
			
		||||
  fNew->prev = fPrev;
 | 
			
		||||
  fPrev->next = fNew;
 | 
			
		||||
  fNew->next = fNext;
 | 
			
		||||
  fNext->prev = fNew;
 | 
			
		||||
 | 
			
		||||
  fNew->anEdge = eOrig;
 | 
			
		||||
  fNew->data = NULL;
 | 
			
		||||
  fNew->trail = NULL;
 | 
			
		||||
  fNew->marked = FALSE;
 | 
			
		||||
 | 
			
		||||
  /* The new face is marked "inside" if the old one was.  This is a
 | 
			
		||||
   * convenience for the common case where a face has been split in two.
 | 
			
		||||
   */
 | 
			
		||||
  fNew->inside = fNext->inside;
 | 
			
		||||
 | 
			
		||||
  /* fix other edges on this face loop */
 | 
			
		||||
  e = eOrig;
 | 
			
		||||
  do {
 | 
			
		||||
    e->Lface = fNew;
 | 
			
		||||
    e = e->Lnext;
 | 
			
		||||
  } while( e != eOrig );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* KillEdge( eDel ) destroys an edge (the half-edges eDel and eDel->Sym),
 | 
			
		||||
 * and removes from the global edge list.
 | 
			
		||||
 */
 | 
			
		||||
static void KillEdge( GLUhalfEdge *eDel )
 | 
			
		||||
{
 | 
			
		||||
  GLUhalfEdge *ePrev, *eNext;
 | 
			
		||||
 | 
			
		||||
  /* Half-edges are allocated in pairs, see EdgePair above */
 | 
			
		||||
  if( eDel->Sym < eDel ) { eDel = eDel->Sym; }
 | 
			
		||||
 | 
			
		||||
  /* delete from circular doubly-linked list */
 | 
			
		||||
  eNext = eDel->next;
 | 
			
		||||
  ePrev = eDel->Sym->next;
 | 
			
		||||
  eNext->Sym->next = ePrev;
 | 
			
		||||
  ePrev->Sym->next = eNext;
 | 
			
		||||
 | 
			
		||||
  memFree( eDel );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* KillVertex( vDel ) destroys a vertex and removes it from the global
 | 
			
		||||
 * vertex list.  It updates the vertex loop to point to a given new vertex.
 | 
			
		||||
 */
 | 
			
		||||
static void KillVertex( GLUvertex *vDel, GLUvertex *newOrg )
 | 
			
		||||
{
 | 
			
		||||
  GLUhalfEdge *e, *eStart = vDel->anEdge;
 | 
			
		||||
  GLUvertex *vPrev, *vNext;
 | 
			
		||||
 | 
			
		||||
  /* change the origin of all affected edges */
 | 
			
		||||
  e = eStart;
 | 
			
		||||
  do {
 | 
			
		||||
    e->Org = newOrg;
 | 
			
		||||
    e = e->Onext;
 | 
			
		||||
  } while( e != eStart );
 | 
			
		||||
 | 
			
		||||
  /* delete from circular doubly-linked list */
 | 
			
		||||
  vPrev = vDel->prev;
 | 
			
		||||
  vNext = vDel->next;
 | 
			
		||||
  vNext->prev = vPrev;
 | 
			
		||||
  vPrev->next = vNext;
 | 
			
		||||
 | 
			
		||||
  memFree( vDel );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* KillFace( fDel ) destroys a face and removes it from the global face
 | 
			
		||||
 * list.  It updates the face loop to point to a given new face.
 | 
			
		||||
 */
 | 
			
		||||
static void KillFace( GLUface *fDel, GLUface *newLface )
 | 
			
		||||
{
 | 
			
		||||
  GLUhalfEdge *e, *eStart = fDel->anEdge;
 | 
			
		||||
  GLUface *fPrev, *fNext;
 | 
			
		||||
 | 
			
		||||
  /* change the left face of all affected edges */
 | 
			
		||||
  e = eStart;
 | 
			
		||||
  do {
 | 
			
		||||
    e->Lface = newLface;
 | 
			
		||||
    e = e->Lnext;
 | 
			
		||||
  } while( e != eStart );
 | 
			
		||||
 | 
			
		||||
  /* delete from circular doubly-linked list */
 | 
			
		||||
  fPrev = fDel->prev;
 | 
			
		||||
  fNext = fDel->next;
 | 
			
		||||
  fNext->prev = fPrev;
 | 
			
		||||
  fPrev->next = fNext;
 | 
			
		||||
 | 
			
		||||
  memFree( fDel );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/****************** Basic Edge Operations **********************/
 | 
			
		||||
 | 
			
		||||
/* __gl_meshMakeEdge creates one edge, two vertices, and a loop (face).
 | 
			
		||||
 * The loop consists of the two new half-edges.
 | 
			
		||||
 */
 | 
			
		||||
GLUhalfEdge *__gl_meshMakeEdge( GLUmesh *mesh )
 | 
			
		||||
{
 | 
			
		||||
  GLUvertex *newVertex1= allocVertex();
 | 
			
		||||
  GLUvertex *newVertex2= allocVertex();
 | 
			
		||||
  GLUface *newFace= allocFace();
 | 
			
		||||
  GLUhalfEdge *e;
 | 
			
		||||
 | 
			
		||||
  /* if any one is null then all get freed */
 | 
			
		||||
  if (newVertex1 == NULL || newVertex2 == NULL || newFace == NULL) {
 | 
			
		||||
     if (newVertex1 != NULL) memFree(newVertex1);
 | 
			
		||||
     if (newVertex2 != NULL) memFree(newVertex2);
 | 
			
		||||
     if (newFace != NULL) memFree(newFace);     
 | 
			
		||||
     return NULL;
 | 
			
		||||
  } 
 | 
			
		||||
 | 
			
		||||
  e = MakeEdge( &mesh->eHead );
 | 
			
		||||
  if (e == NULL) {
 | 
			
		||||
     memFree(newVertex1);
 | 
			
		||||
     memFree(newVertex2);
 | 
			
		||||
     memFree(newFace);
 | 
			
		||||
     return NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  MakeVertex( newVertex1, e, &mesh->vHead );
 | 
			
		||||
  MakeVertex( newVertex2, e->Sym, &mesh->vHead );
 | 
			
		||||
  MakeFace( newFace, e, &mesh->fHead );
 | 
			
		||||
  return e;
 | 
			
		||||
}
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
/* __gl_meshSplice( eOrg, eDst ) is the basic operation for changing the
 | 
			
		||||
 * mesh connectivity and topology.  It changes the mesh so that
 | 
			
		||||
 *	eOrg->Onext <- OLD( eDst->Onext )
 | 
			
		||||
 *	eDst->Onext <- OLD( eOrg->Onext )
 | 
			
		||||
 * where OLD(...) means the value before the meshSplice operation.
 | 
			
		||||
 *
 | 
			
		||||
 * This can have two effects on the vertex structure:
 | 
			
		||||
 *  - if eOrg->Org != eDst->Org, the two vertices are merged together
 | 
			
		||||
 *  - if eOrg->Org == eDst->Org, the origin is split into two vertices
 | 
			
		||||
 * In both cases, eDst->Org is changed and eOrg->Org is untouched.
 | 
			
		||||
 *
 | 
			
		||||
 * Similarly (and independently) for the face structure,
 | 
			
		||||
 *  - if eOrg->Lface == eDst->Lface, one loop is split into two
 | 
			
		||||
 *  - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one
 | 
			
		||||
 * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected.
 | 
			
		||||
 *
 | 
			
		||||
 * Some special cases:
 | 
			
		||||
 * If eDst == eOrg, the operation has no effect.
 | 
			
		||||
 * If eDst == eOrg->Lnext, the new face will have a single edge.
 | 
			
		||||
 * If eDst == eOrg->Lprev, the old face will have a single edge.
 | 
			
		||||
 * If eDst == eOrg->Onext, the new vertex will have a single edge.
 | 
			
		||||
 * If eDst == eOrg->Oprev, the old vertex will have a single edge.
 | 
			
		||||
 */
 | 
			
		||||
int __gl_meshSplice( GLUhalfEdge *eOrg, GLUhalfEdge *eDst )
 | 
			
		||||
{
 | 
			
		||||
  int joiningLoops = FALSE;
 | 
			
		||||
  int joiningVertices = FALSE;
 | 
			
		||||
 | 
			
		||||
  if( eOrg == eDst ) return 1;
 | 
			
		||||
 | 
			
		||||
  if( eDst->Org != eOrg->Org ) {
 | 
			
		||||
    /* We are merging two disjoint vertices -- destroy eDst->Org */
 | 
			
		||||
    joiningVertices = TRUE;
 | 
			
		||||
    KillVertex( eDst->Org, eOrg->Org );
 | 
			
		||||
  }
 | 
			
		||||
  if( eDst->Lface != eOrg->Lface ) {
 | 
			
		||||
    /* We are connecting two disjoint loops -- destroy eDst->Lface */
 | 
			
		||||
    joiningLoops = TRUE;
 | 
			
		||||
    KillFace( eDst->Lface, eOrg->Lface );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Change the edge structure */
 | 
			
		||||
  Splice( eDst, eOrg );
 | 
			
		||||
 | 
			
		||||
  if( ! joiningVertices ) {
 | 
			
		||||
    GLUvertex *newVertex= allocVertex();
 | 
			
		||||
    if (newVertex == NULL) return 0;
 | 
			
		||||
 | 
			
		||||
    /* We split one vertex into two -- the new vertex is eDst->Org.
 | 
			
		||||
     * Make sure the old vertex points to a valid half-edge.
 | 
			
		||||
     */
 | 
			
		||||
    MakeVertex( newVertex, eDst, eOrg->Org );
 | 
			
		||||
    eOrg->Org->anEdge = eOrg;
 | 
			
		||||
  }
 | 
			
		||||
  if( ! joiningLoops ) {
 | 
			
		||||
    GLUface *newFace= allocFace();  
 | 
			
		||||
    if (newFace == NULL) return 0;
 | 
			
		||||
 | 
			
		||||
    /* We split one loop into two -- the new loop is eDst->Lface.
 | 
			
		||||
     * Make sure the old face points to a valid half-edge.
 | 
			
		||||
     */
 | 
			
		||||
    MakeFace( newFace, eDst, eOrg->Lface );
 | 
			
		||||
    eOrg->Lface->anEdge = eOrg;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* __gl_meshDelete( eDel ) removes the edge eDel.  There are several cases:
 | 
			
		||||
 * if (eDel->Lface != eDel->Rface), we join two loops into one; the loop
 | 
			
		||||
 * eDel->Lface is deleted.  Otherwise, we are splitting one loop into two;
 | 
			
		||||
 * the newly created loop will contain eDel->Dst.  If the deletion of eDel
 | 
			
		||||
 * would create isolated vertices, those are deleted as well.
 | 
			
		||||
 *
 | 
			
		||||
 * This function could be implemented as two calls to __gl_meshSplice
 | 
			
		||||
 * plus a few calls to memFree, but this would allocate and delete
 | 
			
		||||
 * unnecessary vertices and faces.
 | 
			
		||||
 */
 | 
			
		||||
int __gl_meshDelete( GLUhalfEdge *eDel )
 | 
			
		||||
{
 | 
			
		||||
  GLUhalfEdge *eDelSym = eDel->Sym;
 | 
			
		||||
  int joiningLoops = FALSE;
 | 
			
		||||
 | 
			
		||||
  /* First step: disconnect the origin vertex eDel->Org.  We make all
 | 
			
		||||
   * changes to get a consistent mesh in this "intermediate" state.
 | 
			
		||||
   */
 | 
			
		||||
  if( eDel->Lface != eDel->Rface ) {
 | 
			
		||||
    /* We are joining two loops into one -- remove the left face */
 | 
			
		||||
    joiningLoops = TRUE;
 | 
			
		||||
    KillFace( eDel->Lface, eDel->Rface );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if( eDel->Onext == eDel ) {
 | 
			
		||||
    KillVertex( eDel->Org, NULL );
 | 
			
		||||
  } else {
 | 
			
		||||
    /* Make sure that eDel->Org and eDel->Rface point to valid half-edges */
 | 
			
		||||
    eDel->Rface->anEdge = eDel->Oprev;
 | 
			
		||||
    eDel->Org->anEdge = eDel->Onext;
 | 
			
		||||
 | 
			
		||||
    Splice( eDel, eDel->Oprev );
 | 
			
		||||
    if( ! joiningLoops ) {
 | 
			
		||||
      GLUface *newFace= allocFace();
 | 
			
		||||
      if (newFace == NULL) return 0; 
 | 
			
		||||
 | 
			
		||||
      /* We are splitting one loop into two -- create a new loop for eDel. */
 | 
			
		||||
      MakeFace( newFace, eDel, eDel->Lface );
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Claim: the mesh is now in a consistent state, except that eDel->Org
 | 
			
		||||
   * may have been deleted.  Now we disconnect eDel->Dst.
 | 
			
		||||
   */
 | 
			
		||||
  if( eDelSym->Onext == eDelSym ) {
 | 
			
		||||
    KillVertex( eDelSym->Org, NULL );
 | 
			
		||||
    KillFace( eDelSym->Lface, NULL );
 | 
			
		||||
  } else {
 | 
			
		||||
    /* Make sure that eDel->Dst and eDel->Lface point to valid half-edges */
 | 
			
		||||
    eDel->Lface->anEdge = eDelSym->Oprev;
 | 
			
		||||
    eDelSym->Org->anEdge = eDelSym->Onext;
 | 
			
		||||
    Splice( eDelSym, eDelSym->Oprev );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Any isolated vertices or faces have already been freed. */
 | 
			
		||||
  KillEdge( eDel );
 | 
			
		||||
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************** Other Edge Operations **********************/
 | 
			
		||||
 | 
			
		||||
/* All these routines can be implemented with the basic edge
 | 
			
		||||
 * operations above.  They are provided for convenience and efficiency.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* __gl_meshAddEdgeVertex( eOrg ) creates a new edge eNew such that
 | 
			
		||||
 * eNew == eOrg->Lnext, and eNew->Dst is a newly created vertex.
 | 
			
		||||
 * eOrg and eNew will have the same left face.
 | 
			
		||||
 */
 | 
			
		||||
GLUhalfEdge *__gl_meshAddEdgeVertex( GLUhalfEdge *eOrg )
 | 
			
		||||
{
 | 
			
		||||
  GLUhalfEdge *eNewSym;
 | 
			
		||||
  GLUhalfEdge *eNew = MakeEdge( eOrg );
 | 
			
		||||
  if (eNew == NULL) return NULL;
 | 
			
		||||
 | 
			
		||||
  eNewSym = eNew->Sym;
 | 
			
		||||
 | 
			
		||||
  /* Connect the new edge appropriately */
 | 
			
		||||
  Splice( eNew, eOrg->Lnext );
 | 
			
		||||
 | 
			
		||||
  /* Set the vertex and face information */
 | 
			
		||||
  eNew->Org = eOrg->Dst;
 | 
			
		||||
  {
 | 
			
		||||
    GLUvertex *newVertex= allocVertex();
 | 
			
		||||
    if (newVertex == NULL) return NULL;
 | 
			
		||||
 | 
			
		||||
    MakeVertex( newVertex, eNewSym, eNew->Org );
 | 
			
		||||
  }
 | 
			
		||||
  eNew->Lface = eNewSym->Lface = eOrg->Lface;
 | 
			
		||||
 | 
			
		||||
  return eNew;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* __gl_meshSplitEdge( eOrg ) splits eOrg into two edges eOrg and eNew,
 | 
			
		||||
 * such that eNew == eOrg->Lnext.  The new vertex is eOrg->Dst == eNew->Org.
 | 
			
		||||
 * eOrg and eNew will have the same left face.
 | 
			
		||||
 */
 | 
			
		||||
GLUhalfEdge *__gl_meshSplitEdge( GLUhalfEdge *eOrg )
 | 
			
		||||
{
 | 
			
		||||
  GLUhalfEdge *eNew;
 | 
			
		||||
  GLUhalfEdge *tempHalfEdge= __gl_meshAddEdgeVertex( eOrg );
 | 
			
		||||
  if (tempHalfEdge == NULL) return NULL;
 | 
			
		||||
 | 
			
		||||
  eNew = tempHalfEdge->Sym;
 | 
			
		||||
 | 
			
		||||
  /* Disconnect eOrg from eOrg->Dst and connect it to eNew->Org */
 | 
			
		||||
  Splice( eOrg->Sym, eOrg->Sym->Oprev );
 | 
			
		||||
  Splice( eOrg->Sym, eNew );
 | 
			
		||||
 | 
			
		||||
  /* Set the vertex and face information */
 | 
			
		||||
  eOrg->Dst = eNew->Org;
 | 
			
		||||
  eNew->Dst->anEdge = eNew->Sym;	/* may have pointed to eOrg->Sym */
 | 
			
		||||
  eNew->Rface = eOrg->Rface;
 | 
			
		||||
  eNew->winding = eOrg->winding;	/* copy old winding information */
 | 
			
		||||
  eNew->Sym->winding = eOrg->Sym->winding;
 | 
			
		||||
 | 
			
		||||
  return eNew;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* __gl_meshConnect( eOrg, eDst ) creates a new edge from eOrg->Dst
 | 
			
		||||
 * to eDst->Org, and returns the corresponding half-edge eNew.
 | 
			
		||||
 * If eOrg->Lface == eDst->Lface, this splits one loop into two,
 | 
			
		||||
 * and the newly created loop is eNew->Lface.  Otherwise, two disjoint
 | 
			
		||||
 * loops are merged into one, and the loop eDst->Lface is destroyed.
 | 
			
		||||
 *
 | 
			
		||||
 * If (eOrg == eDst), the new face will have only two edges.
 | 
			
		||||
 * If (eOrg->Lnext == eDst), the old face is reduced to a single edge.
 | 
			
		||||
 * If (eOrg->Lnext->Lnext == eDst), the old face is reduced to two edges.
 | 
			
		||||
 */
 | 
			
		||||
GLUhalfEdge *__gl_meshConnect( GLUhalfEdge *eOrg, GLUhalfEdge *eDst )
 | 
			
		||||
{
 | 
			
		||||
  GLUhalfEdge *eNewSym;
 | 
			
		||||
  int joiningLoops = FALSE;  
 | 
			
		||||
  GLUhalfEdge *eNew = MakeEdge( eOrg );
 | 
			
		||||
  if (eNew == NULL) return NULL;
 | 
			
		||||
 | 
			
		||||
  eNewSym = eNew->Sym;
 | 
			
		||||
 | 
			
		||||
  if( eDst->Lface != eOrg->Lface ) {
 | 
			
		||||
    /* We are connecting two disjoint loops -- destroy eDst->Lface */
 | 
			
		||||
    joiningLoops = TRUE;
 | 
			
		||||
    KillFace( eDst->Lface, eOrg->Lface );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Connect the new edge appropriately */
 | 
			
		||||
  Splice( eNew, eOrg->Lnext );
 | 
			
		||||
  Splice( eNewSym, eDst );
 | 
			
		||||
 | 
			
		||||
  /* Set the vertex and face information */
 | 
			
		||||
  eNew->Org = eOrg->Dst;
 | 
			
		||||
  eNewSym->Org = eDst->Org;
 | 
			
		||||
  eNew->Lface = eNewSym->Lface = eOrg->Lface;
 | 
			
		||||
 | 
			
		||||
  /* Make sure the old face points to a valid half-edge */
 | 
			
		||||
  eOrg->Lface->anEdge = eNewSym;
 | 
			
		||||
 | 
			
		||||
  if( ! joiningLoops ) {
 | 
			
		||||
    GLUface *newFace= allocFace();
 | 
			
		||||
    if (newFace == NULL) return NULL;
 | 
			
		||||
 | 
			
		||||
    /* We split one loop into two -- the new loop is eNew->Lface */
 | 
			
		||||
    MakeFace( newFace, eNew, eOrg->Lface );
 | 
			
		||||
  }
 | 
			
		||||
  return eNew;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************** Other Operations **********************/
 | 
			
		||||
 | 
			
		||||
/* __gl_meshZapFace( fZap ) destroys a face and removes it from the
 | 
			
		||||
 * global face list.  All edges of fZap will have a NULL pointer as their
 | 
			
		||||
 * left face.  Any edges which also have a NULL pointer as their right face
 | 
			
		||||
 * are deleted entirely (along with any isolated vertices this produces).
 | 
			
		||||
 * An entire mesh can be deleted by zapping its faces, one at a time,
 | 
			
		||||
 * in any order.  Zapped faces cannot be used in further mesh operations!
 | 
			
		||||
 */
 | 
			
		||||
void __gl_meshZapFace( GLUface *fZap )
 | 
			
		||||
{
 | 
			
		||||
  GLUhalfEdge *eStart = fZap->anEdge;
 | 
			
		||||
  GLUhalfEdge *e, *eNext, *eSym;
 | 
			
		||||
  GLUface *fPrev, *fNext;
 | 
			
		||||
 | 
			
		||||
  /* walk around face, deleting edges whose right face is also NULL */
 | 
			
		||||
  eNext = eStart->Lnext;
 | 
			
		||||
  do {
 | 
			
		||||
    e = eNext;
 | 
			
		||||
    eNext = e->Lnext;
 | 
			
		||||
 | 
			
		||||
    e->Lface = NULL;
 | 
			
		||||
    if( e->Rface == NULL ) {
 | 
			
		||||
      /* delete the edge -- see __gl_MeshDelete above */
 | 
			
		||||
 | 
			
		||||
      if( e->Onext == e ) {
 | 
			
		||||
	KillVertex( e->Org, NULL );
 | 
			
		||||
      } else {
 | 
			
		||||
	/* Make sure that e->Org points to a valid half-edge */
 | 
			
		||||
	e->Org->anEdge = e->Onext;
 | 
			
		||||
	Splice( e, e->Oprev );
 | 
			
		||||
      }
 | 
			
		||||
      eSym = e->Sym;
 | 
			
		||||
      if( eSym->Onext == eSym ) {
 | 
			
		||||
	KillVertex( eSym->Org, NULL );
 | 
			
		||||
      } else {
 | 
			
		||||
	/* Make sure that eSym->Org points to a valid half-edge */
 | 
			
		||||
	eSym->Org->anEdge = eSym->Onext;
 | 
			
		||||
	Splice( eSym, eSym->Oprev );
 | 
			
		||||
      }
 | 
			
		||||
      KillEdge( e );
 | 
			
		||||
    }
 | 
			
		||||
  } while( e != eStart );
 | 
			
		||||
 | 
			
		||||
  /* delete from circular doubly-linked list */
 | 
			
		||||
  fPrev = fZap->prev;
 | 
			
		||||
  fNext = fZap->next;
 | 
			
		||||
  fNext->prev = fPrev;
 | 
			
		||||
  fPrev->next = fNext;
 | 
			
		||||
 | 
			
		||||
  memFree( fZap );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* __gl_meshNewMesh() creates a new mesh with no edges, no vertices,
 | 
			
		||||
 * and no loops (what we usually call a "face").
 | 
			
		||||
 */
 | 
			
		||||
GLUmesh *__gl_meshNewMesh( void )
 | 
			
		||||
{
 | 
			
		||||
  GLUvertex *v;
 | 
			
		||||
  GLUface *f;
 | 
			
		||||
  GLUhalfEdge *e;
 | 
			
		||||
  GLUhalfEdge *eSym;
 | 
			
		||||
  GLUmesh *mesh = (GLUmesh *)memAlloc( sizeof( GLUmesh ));
 | 
			
		||||
  if (mesh == NULL) {
 | 
			
		||||
     return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  v = &mesh->vHead;
 | 
			
		||||
  f = &mesh->fHead;
 | 
			
		||||
  e = &mesh->eHead;
 | 
			
		||||
  eSym = &mesh->eHeadSym;
 | 
			
		||||
 | 
			
		||||
  v->next = v->prev = v;
 | 
			
		||||
  v->anEdge = NULL;
 | 
			
		||||
  v->data = NULL;
 | 
			
		||||
 | 
			
		||||
  f->next = f->prev = f;
 | 
			
		||||
  f->anEdge = NULL;
 | 
			
		||||
  f->data = NULL;
 | 
			
		||||
  f->trail = NULL;
 | 
			
		||||
  f->marked = FALSE;
 | 
			
		||||
  f->inside = FALSE;
 | 
			
		||||
 | 
			
		||||
  e->next = e;
 | 
			
		||||
  e->Sym = eSym;
 | 
			
		||||
  e->Onext = NULL;
 | 
			
		||||
  e->Lnext = NULL;
 | 
			
		||||
  e->Org = NULL;
 | 
			
		||||
  e->Lface = NULL;
 | 
			
		||||
  e->winding = 0;
 | 
			
		||||
  e->activeRegion = NULL;
 | 
			
		||||
 | 
			
		||||
  eSym->next = eSym;
 | 
			
		||||
  eSym->Sym = e;
 | 
			
		||||
  eSym->Onext = NULL;
 | 
			
		||||
  eSym->Lnext = NULL;
 | 
			
		||||
  eSym->Org = NULL;
 | 
			
		||||
  eSym->Lface = NULL;
 | 
			
		||||
  eSym->winding = 0;
 | 
			
		||||
  eSym->activeRegion = NULL;
 | 
			
		||||
 | 
			
		||||
  return mesh;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* __gl_meshUnion( mesh1, mesh2 ) forms the union of all structures in
 | 
			
		||||
 * both meshes, and returns the new mesh (the old meshes are destroyed).
 | 
			
		||||
 */
 | 
			
		||||
GLUmesh *__gl_meshUnion( GLUmesh *mesh1, GLUmesh *mesh2 )
 | 
			
		||||
{
 | 
			
		||||
  GLUface *f1 = &mesh1->fHead;
 | 
			
		||||
  GLUvertex *v1 = &mesh1->vHead;
 | 
			
		||||
  GLUhalfEdge *e1 = &mesh1->eHead;
 | 
			
		||||
  GLUface *f2 = &mesh2->fHead;
 | 
			
		||||
  GLUvertex *v2 = &mesh2->vHead;
 | 
			
		||||
  GLUhalfEdge *e2 = &mesh2->eHead;
 | 
			
		||||
 | 
			
		||||
  /* Add the faces, vertices, and edges of mesh2 to those of mesh1 */
 | 
			
		||||
  if( f2->next != f2 ) {
 | 
			
		||||
    f1->prev->next = f2->next;
 | 
			
		||||
    f2->next->prev = f1->prev;
 | 
			
		||||
    f2->prev->next = f1;
 | 
			
		||||
    f1->prev = f2->prev;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if( v2->next != v2 ) {
 | 
			
		||||
    v1->prev->next = v2->next;
 | 
			
		||||
    v2->next->prev = v1->prev;
 | 
			
		||||
    v2->prev->next = v1;
 | 
			
		||||
    v1->prev = v2->prev;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if( e2->next != e2 ) {
 | 
			
		||||
    e1->Sym->next->Sym->next = e2->next;
 | 
			
		||||
    e2->next->Sym->next = e1->Sym->next;
 | 
			
		||||
    e2->Sym->next->Sym->next = e1;
 | 
			
		||||
    e1->Sym->next = e2->Sym->next;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  memFree( mesh2 );
 | 
			
		||||
  return mesh1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef DELETE_BY_ZAPPING
 | 
			
		||||
 | 
			
		||||
/* __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh.
 | 
			
		||||
 */
 | 
			
		||||
void __gl_meshDeleteMesh( GLUmesh *mesh )
 | 
			
		||||
{
 | 
			
		||||
  GLUface *fHead = &mesh->fHead;
 | 
			
		||||
 | 
			
		||||
  while( fHead->next != fHead ) {
 | 
			
		||||
    __gl_meshZapFace( fHead->next );
 | 
			
		||||
  }
 | 
			
		||||
  assert( mesh->vHead.next == &mesh->vHead );
 | 
			
		||||
 | 
			
		||||
  memFree( mesh );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
/* __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh.
 | 
			
		||||
 */
 | 
			
		||||
void __gl_meshDeleteMesh( GLUmesh *mesh )
 | 
			
		||||
{
 | 
			
		||||
  GLUface *f, *fNext;
 | 
			
		||||
  GLUvertex *v, *vNext;
 | 
			
		||||
  GLUhalfEdge *e, *eNext;
 | 
			
		||||
 | 
			
		||||
  for( f = mesh->fHead.next; f != &mesh->fHead; f = fNext ) {
 | 
			
		||||
    fNext = f->next;
 | 
			
		||||
    memFree( f );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for( v = mesh->vHead.next; v != &mesh->vHead; v = vNext ) {
 | 
			
		||||
    vNext = v->next;
 | 
			
		||||
    memFree( v );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for( e = mesh->eHead.next; e != &mesh->eHead; e = eNext ) {
 | 
			
		||||
    /* One call frees both e and e->Sym (see EdgePair above) */
 | 
			
		||||
    eNext = e->next;
 | 
			
		||||
    memFree( e );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  memFree( mesh );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
 | 
			
		||||
/* __gl_meshCheckMesh( mesh ) checks a mesh for self-consistency.
 | 
			
		||||
 */
 | 
			
		||||
void __gl_meshCheckMesh( GLUmesh *mesh )
 | 
			
		||||
{
 | 
			
		||||
  GLUface *fHead = &mesh->fHead;
 | 
			
		||||
  GLUvertex *vHead = &mesh->vHead;
 | 
			
		||||
  GLUhalfEdge *eHead = &mesh->eHead;
 | 
			
		||||
  GLUface *f, *fPrev;
 | 
			
		||||
  GLUvertex *v, *vPrev;
 | 
			
		||||
  GLUhalfEdge *e, *ePrev;
 | 
			
		||||
 | 
			
		||||
  fPrev = fHead;
 | 
			
		||||
  for( fPrev = fHead ; (f = fPrev->next) != fHead; fPrev = f) {
 | 
			
		||||
    assert( f->prev == fPrev );
 | 
			
		||||
    e = f->anEdge;
 | 
			
		||||
    do {
 | 
			
		||||
      assert( e->Sym != e );
 | 
			
		||||
      assert( e->Sym->Sym == e );
 | 
			
		||||
      assert( e->Lnext->Onext->Sym == e );
 | 
			
		||||
      assert( e->Onext->Sym->Lnext == e );
 | 
			
		||||
      assert( e->Lface == f );
 | 
			
		||||
      e = e->Lnext;
 | 
			
		||||
    } while( e != f->anEdge );
 | 
			
		||||
  }
 | 
			
		||||
  assert( f->prev == fPrev && f->anEdge == NULL && f->data == NULL );
 | 
			
		||||
 | 
			
		||||
  vPrev = vHead;
 | 
			
		||||
  for( vPrev = vHead ; (v = vPrev->next) != vHead; vPrev = v) {
 | 
			
		||||
    assert( v->prev == vPrev );
 | 
			
		||||
    e = v->anEdge;
 | 
			
		||||
    do {
 | 
			
		||||
      assert( e->Sym != e );
 | 
			
		||||
      assert( e->Sym->Sym == e );
 | 
			
		||||
      assert( e->Lnext->Onext->Sym == e );
 | 
			
		||||
      assert( e->Onext->Sym->Lnext == e );
 | 
			
		||||
      assert( e->Org == v );
 | 
			
		||||
      e = e->Onext;
 | 
			
		||||
    } while( e != v->anEdge );
 | 
			
		||||
  }
 | 
			
		||||
  assert( v->prev == vPrev && v->anEdge == NULL && v->data == NULL );
 | 
			
		||||
 | 
			
		||||
  ePrev = eHead;
 | 
			
		||||
  for( ePrev = eHead ; (e = ePrev->next) != eHead; ePrev = e) {
 | 
			
		||||
    assert( e->Sym->next == ePrev->Sym );
 | 
			
		||||
    assert( e->Sym != e );
 | 
			
		||||
    assert( e->Sym->Sym == e );
 | 
			
		||||
    assert( e->Org != NULL );
 | 
			
		||||
    assert( e->Dst != NULL );
 | 
			
		||||
    assert( e->Lnext->Onext->Sym == e );
 | 
			
		||||
    assert( e->Onext->Sym->Lnext == e );
 | 
			
		||||
  }
 | 
			
		||||
  assert( e->Sym->next == ePrev->Sym
 | 
			
		||||
       && e->Sym == &mesh->eHeadSym
 | 
			
		||||
       && e->Sym->Sym == e
 | 
			
		||||
       && e->Org == NULL && e->Dst == NULL
 | 
			
		||||
       && e->Lface == NULL && e->Rface == NULL );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,266 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
** Author: Eric Veach, July 1994.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __mesh_h_
 | 
			
		||||
#define __mesh_h_
 | 
			
		||||
 | 
			
		||||
#include <GL/gl.h>
 | 
			
		||||
 | 
			
		||||
typedef struct GLUmesh GLUmesh; 
 | 
			
		||||
 | 
			
		||||
typedef struct GLUvertex GLUvertex;
 | 
			
		||||
typedef struct GLUface GLUface;
 | 
			
		||||
typedef struct GLUhalfEdge GLUhalfEdge;
 | 
			
		||||
 | 
			
		||||
typedef struct ActiveRegion ActiveRegion;	/* Internal data */
 | 
			
		||||
 | 
			
		||||
/* The mesh structure is similar in spirit, notation, and operations
 | 
			
		||||
 * to the "quad-edge" structure (see L. Guibas and J. Stolfi, Primitives
 | 
			
		||||
 * for the manipulation of general subdivisions and the computation of
 | 
			
		||||
 * Voronoi diagrams, ACM Transactions on Graphics, 4(2):74-123, April 1985).
 | 
			
		||||
 * For a simplified description, see the course notes for CS348a,
 | 
			
		||||
 * "Mathematical Foundations of Computer Graphics", available at the
 | 
			
		||||
 * Stanford bookstore (and taught during the fall quarter).
 | 
			
		||||
 * The implementation also borrows a tiny subset of the graph-based approach
 | 
			
		||||
 * use in Mantyla's Geometric Work Bench (see M. Mantyla, An Introduction
 | 
			
		||||
 * to Sold Modeling, Computer Science Press, Rockville, Maryland, 1988).
 | 
			
		||||
 *
 | 
			
		||||
 * The fundamental data structure is the "half-edge".  Two half-edges
 | 
			
		||||
 * go together to make an edge, but they point in opposite directions.
 | 
			
		||||
 * Each half-edge has a pointer to its mate (the "symmetric" half-edge Sym),
 | 
			
		||||
 * its origin vertex (Org), the face on its left side (Lface), and the
 | 
			
		||||
 * adjacent half-edges in the CCW direction around the origin vertex
 | 
			
		||||
 * (Onext) and around the left face (Lnext).  There is also a "next"
 | 
			
		||||
 * pointer for the global edge list (see below).
 | 
			
		||||
 *
 | 
			
		||||
 * The notation used for mesh navigation:
 | 
			
		||||
 *	Sym   = the mate of a half-edge (same edge, but opposite direction)
 | 
			
		||||
 *	Onext = edge CCW around origin vertex (keep same origin)
 | 
			
		||||
 *	Dnext = edge CCW around destination vertex (keep same dest)
 | 
			
		||||
 *	Lnext = edge CCW around left face (dest becomes new origin)
 | 
			
		||||
 *	Rnext = edge CCW around right face (origin becomes new dest)
 | 
			
		||||
 *
 | 
			
		||||
 * "prev" means to substitute CW for CCW in the definitions above.
 | 
			
		||||
 *
 | 
			
		||||
 * The mesh keeps global lists of all vertices, faces, and edges,
 | 
			
		||||
 * stored as doubly-linked circular lists with a dummy header node.
 | 
			
		||||
 * The mesh stores pointers to these dummy headers (vHead, fHead, eHead).
 | 
			
		||||
 *
 | 
			
		||||
 * The circular edge list is special; since half-edges always occur
 | 
			
		||||
 * in pairs (e and e->Sym), each half-edge stores a pointer in only
 | 
			
		||||
 * one direction.  Starting at eHead and following the e->next pointers
 | 
			
		||||
 * will visit each *edge* once (ie. e or e->Sym, but not both).
 | 
			
		||||
 * e->Sym stores a pointer in the opposite direction, thus it is
 | 
			
		||||
 * always true that e->Sym->next->Sym->next == e.
 | 
			
		||||
 *
 | 
			
		||||
 * Each vertex has a pointer to next and previous vertices in the
 | 
			
		||||
 * circular list, and a pointer to a half-edge with this vertex as
 | 
			
		||||
 * the origin (NULL if this is the dummy header).  There is also a
 | 
			
		||||
 * field "data" for client data.
 | 
			
		||||
 *
 | 
			
		||||
 * Each face has a pointer to the next and previous faces in the
 | 
			
		||||
 * circular list, and a pointer to a half-edge with this face as
 | 
			
		||||
 * the left face (NULL if this is the dummy header).  There is also
 | 
			
		||||
 * a field "data" for client data.
 | 
			
		||||
 *
 | 
			
		||||
 * Note that what we call a "face" is really a loop; faces may consist
 | 
			
		||||
 * of more than one loop (ie. not simply connected), but there is no
 | 
			
		||||
 * record of this in the data structure.  The mesh may consist of
 | 
			
		||||
 * several disconnected regions, so it may not be possible to visit
 | 
			
		||||
 * the entire mesh by starting at a half-edge and traversing the edge
 | 
			
		||||
 * structure.
 | 
			
		||||
 *
 | 
			
		||||
 * The mesh does NOT support isolated vertices; a vertex is deleted along
 | 
			
		||||
 * with its last edge.  Similarly when two faces are merged, one of the
 | 
			
		||||
 * faces is deleted (see __gl_meshDelete below).  For mesh operations,
 | 
			
		||||
 * all face (loop) and vertex pointers must not be NULL.  However, once
 | 
			
		||||
 * mesh manipulation is finished, __gl_MeshZapFace can be used to delete
 | 
			
		||||
 * faces of the mesh, one at a time.  All external faces can be "zapped"
 | 
			
		||||
 * before the mesh is returned to the client; then a NULL face indicates
 | 
			
		||||
 * a region which is not part of the output polygon.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
struct GLUvertex {
 | 
			
		||||
  GLUvertex	*next;		/* next vertex (never NULL) */
 | 
			
		||||
  GLUvertex	*prev;		/* previous vertex (never NULL) */
 | 
			
		||||
  GLUhalfEdge	*anEdge;	/* a half-edge with this origin */
 | 
			
		||||
  void		*data;		/* client's data */
 | 
			
		||||
 | 
			
		||||
  /* Internal data (keep hidden) */
 | 
			
		||||
  GLdouble	coords[3];	/* vertex location in 3D */
 | 
			
		||||
  GLdouble	s, t;		/* projection onto the sweep plane */
 | 
			
		||||
  long		pqHandle;	/* to allow deletion from priority queue */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct GLUface {
 | 
			
		||||
  GLUface	*next;		/* next face (never NULL) */
 | 
			
		||||
  GLUface	*prev;		/* previous face (never NULL) */
 | 
			
		||||
  GLUhalfEdge	*anEdge;	/* a half edge with this left face */
 | 
			
		||||
  void		*data;		/* room for client's data */
 | 
			
		||||
 | 
			
		||||
  /* Internal data (keep hidden) */
 | 
			
		||||
  GLUface	*trail;		/* "stack" for conversion to strips */
 | 
			
		||||
  GLboolean	marked;		/* flag for conversion to strips */
 | 
			
		||||
  GLboolean	inside;		/* this face is in the polygon interior */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct GLUhalfEdge {
 | 
			
		||||
  GLUhalfEdge	*next;		/* doubly-linked list (prev==Sym->next) */
 | 
			
		||||
  GLUhalfEdge	*Sym;		/* same edge, opposite direction */
 | 
			
		||||
  GLUhalfEdge	*Onext;		/* next edge CCW around origin */
 | 
			
		||||
  GLUhalfEdge	*Lnext;		/* next edge CCW around left face */
 | 
			
		||||
  GLUvertex	*Org;		/* origin vertex (Overtex too long) */
 | 
			
		||||
  GLUface	*Lface;		/* left face */
 | 
			
		||||
 | 
			
		||||
  /* Internal data (keep hidden) */
 | 
			
		||||
  ActiveRegion	*activeRegion;	/* a region with this upper edge (sweep.c) */
 | 
			
		||||
  int		winding;	/* change in winding number when crossing
 | 
			
		||||
                                   from the right face to the left face */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define	Rface	Sym->Lface
 | 
			
		||||
#define Dst	Sym->Org
 | 
			
		||||
 | 
			
		||||
#define Oprev	Sym->Lnext
 | 
			
		||||
#define Lprev   Onext->Sym
 | 
			
		||||
#define Dprev	Lnext->Sym
 | 
			
		||||
#define Rprev	Sym->Onext
 | 
			
		||||
#define Dnext	Rprev->Sym	/* 3 pointers */
 | 
			
		||||
#define Rnext	Oprev->Sym	/* 3 pointers */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct GLUmesh {
 | 
			
		||||
  GLUvertex	vHead;		/* dummy header for vertex list */
 | 
			
		||||
  GLUface	fHead;		/* dummy header for face list */
 | 
			
		||||
  GLUhalfEdge	eHead;		/* dummy header for edge list */
 | 
			
		||||
  GLUhalfEdge	eHeadSym;	/* and its symmetric counterpart */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* The mesh operations below have three motivations: completeness,
 | 
			
		||||
 * convenience, and efficiency.  The basic mesh operations are MakeEdge,
 | 
			
		||||
 * Splice, and Delete.  All the other edge operations can be implemented
 | 
			
		||||
 * in terms of these.  The other operations are provided for convenience
 | 
			
		||||
 * and/or efficiency.
 | 
			
		||||
 *
 | 
			
		||||
 * When a face is split or a vertex is added, they are inserted into the
 | 
			
		||||
 * global list *before* the existing vertex or face (ie. e->Org or e->Lface).
 | 
			
		||||
 * This makes it easier to process all vertices or faces in the global lists
 | 
			
		||||
 * without worrying about processing the same data twice.  As a convenience,
 | 
			
		||||
 * when a face is split, the "inside" flag is copied from the old face.
 | 
			
		||||
 * Other internal data (v->data, v->activeRegion, f->data, f->marked,
 | 
			
		||||
 * f->trail, e->winding) is set to zero.
 | 
			
		||||
 *
 | 
			
		||||
 * ********************** Basic Edge Operations **************************
 | 
			
		||||
 *
 | 
			
		||||
 * __gl_meshMakeEdge( mesh ) creates one edge, two vertices, and a loop.
 | 
			
		||||
 * The loop (face) consists of the two new half-edges.
 | 
			
		||||
 *
 | 
			
		||||
 * __gl_meshSplice( eOrg, eDst ) is the basic operation for changing the
 | 
			
		||||
 * mesh connectivity and topology.  It changes the mesh so that
 | 
			
		||||
 *	eOrg->Onext <- OLD( eDst->Onext )
 | 
			
		||||
 *	eDst->Onext <- OLD( eOrg->Onext )
 | 
			
		||||
 * where OLD(...) means the value before the meshSplice operation.
 | 
			
		||||
 *
 | 
			
		||||
 * This can have two effects on the vertex structure:
 | 
			
		||||
 *  - if eOrg->Org != eDst->Org, the two vertices are merged together
 | 
			
		||||
 *  - if eOrg->Org == eDst->Org, the origin is split into two vertices
 | 
			
		||||
 * In both cases, eDst->Org is changed and eOrg->Org is untouched.
 | 
			
		||||
 *
 | 
			
		||||
 * Similarly (and independently) for the face structure,
 | 
			
		||||
 *  - if eOrg->Lface == eDst->Lface, one loop is split into two
 | 
			
		||||
 *  - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one
 | 
			
		||||
 * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected.
 | 
			
		||||
 *
 | 
			
		||||
 * __gl_meshDelete( eDel ) removes the edge eDel.  There are several cases:
 | 
			
		||||
 * if (eDel->Lface != eDel->Rface), we join two loops into one; the loop
 | 
			
		||||
 * eDel->Lface is deleted.  Otherwise, we are splitting one loop into two;
 | 
			
		||||
 * the newly created loop will contain eDel->Dst.  If the deletion of eDel
 | 
			
		||||
 * would create isolated vertices, those are deleted as well.
 | 
			
		||||
 *
 | 
			
		||||
 * ********************** Other Edge Operations **************************
 | 
			
		||||
 *
 | 
			
		||||
 * __gl_meshAddEdgeVertex( eOrg ) creates a new edge eNew such that
 | 
			
		||||
 * eNew == eOrg->Lnext, and eNew->Dst is a newly created vertex.
 | 
			
		||||
 * eOrg and eNew will have the same left face.
 | 
			
		||||
 *
 | 
			
		||||
 * __gl_meshSplitEdge( eOrg ) splits eOrg into two edges eOrg and eNew,
 | 
			
		||||
 * such that eNew == eOrg->Lnext.  The new vertex is eOrg->Dst == eNew->Org.
 | 
			
		||||
 * eOrg and eNew will have the same left face.
 | 
			
		||||
 *
 | 
			
		||||
 * __gl_meshConnect( eOrg, eDst ) creates a new edge from eOrg->Dst
 | 
			
		||||
 * to eDst->Org, and returns the corresponding half-edge eNew.
 | 
			
		||||
 * If eOrg->Lface == eDst->Lface, this splits one loop into two,
 | 
			
		||||
 * and the newly created loop is eNew->Lface.  Otherwise, two disjoint
 | 
			
		||||
 * loops are merged into one, and the loop eDst->Lface is destroyed.
 | 
			
		||||
 *
 | 
			
		||||
 * ************************ Other Operations *****************************
 | 
			
		||||
 *
 | 
			
		||||
 * __gl_meshNewMesh() creates a new mesh with no edges, no vertices,
 | 
			
		||||
 * and no loops (what we usually call a "face").
 | 
			
		||||
 *
 | 
			
		||||
 * __gl_meshUnion( mesh1, mesh2 ) forms the union of all structures in
 | 
			
		||||
 * both meshes, and returns the new mesh (the old meshes are destroyed).
 | 
			
		||||
 *
 | 
			
		||||
 * __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh.
 | 
			
		||||
 *
 | 
			
		||||
 * __gl_meshZapFace( fZap ) destroys a face and removes it from the
 | 
			
		||||
 * global face list.  All edges of fZap will have a NULL pointer as their
 | 
			
		||||
 * left face.  Any edges which also have a NULL pointer as their right face
 | 
			
		||||
 * are deleted entirely (along with any isolated vertices this produces).
 | 
			
		||||
 * An entire mesh can be deleted by zapping its faces, one at a time,
 | 
			
		||||
 * in any order.  Zapped faces cannot be used in further mesh operations!
 | 
			
		||||
 *
 | 
			
		||||
 * __gl_meshCheckMesh( mesh ) checks a mesh for self-consistency.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
GLUhalfEdge	*__gl_meshMakeEdge( GLUmesh *mesh );
 | 
			
		||||
int		__gl_meshSplice( GLUhalfEdge *eOrg, GLUhalfEdge *eDst );
 | 
			
		||||
int		__gl_meshDelete( GLUhalfEdge *eDel );
 | 
			
		||||
 | 
			
		||||
GLUhalfEdge	*__gl_meshAddEdgeVertex( GLUhalfEdge *eOrg );
 | 
			
		||||
GLUhalfEdge	*__gl_meshSplitEdge( GLUhalfEdge *eOrg );
 | 
			
		||||
GLUhalfEdge	*__gl_meshConnect( GLUhalfEdge *eOrg, GLUhalfEdge *eDst );
 | 
			
		||||
 | 
			
		||||
GLUmesh		*__gl_meshNewMesh( void );
 | 
			
		||||
GLUmesh		*__gl_meshUnion( GLUmesh *mesh1, GLUmesh *mesh2 );
 | 
			
		||||
void		__gl_meshDeleteMesh( GLUmesh *mesh );
 | 
			
		||||
void		__gl_meshZapFace( GLUface *fZap );
 | 
			
		||||
 | 
			
		||||
#ifdef NDEBUG
 | 
			
		||||
#define		__gl_meshCheckMesh( mesh )
 | 
			
		||||
#else
 | 
			
		||||
void		__gl_meshCheckMesh( GLUmesh *mesh );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,257 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
** Author: Eric Veach, July 1994.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "gluos.h"
 | 
			
		||||
#include "mesh.h"
 | 
			
		||||
#include "tess.h"
 | 
			
		||||
#include "normal.h"
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#ifndef TRUE
 | 
			
		||||
#define TRUE 1
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef FALSE
 | 
			
		||||
#define FALSE 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define Dot(u,v)	(u[0]*v[0] + u[1]*v[1] + u[2]*v[2])
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
static void Normalize( GLdouble v[3] )
 | 
			
		||||
{
 | 
			
		||||
  GLdouble len = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
 | 
			
		||||
 | 
			
		||||
  assert( len > 0 );
 | 
			
		||||
  len = sqrt( len );
 | 
			
		||||
  v[0] /= len;
 | 
			
		||||
  v[1] /= len;
 | 
			
		||||
  v[2] /= len;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#undef	ABS
 | 
			
		||||
#define ABS(x)	((x) < 0 ? -(x) : (x))
 | 
			
		||||
 | 
			
		||||
static int LongAxis( GLdouble v[3] )
 | 
			
		||||
{
 | 
			
		||||
  int i = 0;
 | 
			
		||||
 | 
			
		||||
  if( ABS(v[1]) > ABS(v[0]) ) { i = 1; }
 | 
			
		||||
  if( ABS(v[2]) > ABS(v[i]) ) { i = 2; }
 | 
			
		||||
  return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ComputeNormal( GLUtesselator *tess, GLdouble norm[3] )
 | 
			
		||||
{
 | 
			
		||||
  GLUvertex *v, *v1, *v2;
 | 
			
		||||
  GLdouble c, tLen2, maxLen2;
 | 
			
		||||
  GLdouble maxVal[3], minVal[3], d1[3], d2[3], tNorm[3];
 | 
			
		||||
  GLUvertex *maxVert[3], *minVert[3];
 | 
			
		||||
  GLUvertex *vHead = &tess->mesh->vHead;
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  maxVal[0] = maxVal[1] = maxVal[2] = -2 * GLU_TESS_MAX_COORD;
 | 
			
		||||
  minVal[0] = minVal[1] = minVal[2] = 2 * GLU_TESS_MAX_COORD;
 | 
			
		||||
 | 
			
		||||
  for( v = vHead->next; v != vHead; v = v->next ) {
 | 
			
		||||
    for( i = 0; i < 3; ++i ) {
 | 
			
		||||
      c = v->coords[i];
 | 
			
		||||
      if( c < minVal[i] ) { minVal[i] = c; minVert[i] = v; }
 | 
			
		||||
      if( c > maxVal[i] ) { maxVal[i] = c; maxVert[i] = v; }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Find two vertices separated by at least 1/sqrt(3) of the maximum
 | 
			
		||||
   * distance between any two vertices
 | 
			
		||||
   */
 | 
			
		||||
  i = 0;
 | 
			
		||||
  if( maxVal[1] - minVal[1] > maxVal[0] - minVal[0] ) { i = 1; }
 | 
			
		||||
  if( maxVal[2] - minVal[2] > maxVal[i] - minVal[i] ) { i = 2; }
 | 
			
		||||
  if( minVal[i] >= maxVal[i] ) {
 | 
			
		||||
    /* All vertices are the same -- normal doesn't matter */
 | 
			
		||||
    norm[0] = 0; norm[1] = 0; norm[2] = 1;
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Look for a third vertex which forms the triangle with maximum area
 | 
			
		||||
   * (Length of normal == twice the triangle area)
 | 
			
		||||
   */
 | 
			
		||||
  maxLen2 = 0;
 | 
			
		||||
  v1 = minVert[i];
 | 
			
		||||
  v2 = maxVert[i];
 | 
			
		||||
  d1[0] = v1->coords[0] - v2->coords[0];
 | 
			
		||||
  d1[1] = v1->coords[1] - v2->coords[1];
 | 
			
		||||
  d1[2] = v1->coords[2] - v2->coords[2];
 | 
			
		||||
  for( v = vHead->next; v != vHead; v = v->next ) {
 | 
			
		||||
    d2[0] = v->coords[0] - v2->coords[0];
 | 
			
		||||
    d2[1] = v->coords[1] - v2->coords[1];
 | 
			
		||||
    d2[2] = v->coords[2] - v2->coords[2];
 | 
			
		||||
    tNorm[0] = d1[1]*d2[2] - d1[2]*d2[1];
 | 
			
		||||
    tNorm[1] = d1[2]*d2[0] - d1[0]*d2[2];
 | 
			
		||||
    tNorm[2] = d1[0]*d2[1] - d1[1]*d2[0];
 | 
			
		||||
    tLen2 = tNorm[0]*tNorm[0] + tNorm[1]*tNorm[1] + tNorm[2]*tNorm[2];
 | 
			
		||||
    if( tLen2 > maxLen2 ) {
 | 
			
		||||
      maxLen2 = tLen2;
 | 
			
		||||
      norm[0] = tNorm[0];
 | 
			
		||||
      norm[1] = tNorm[1];
 | 
			
		||||
      norm[2] = tNorm[2];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if( maxLen2 <= 0 ) {
 | 
			
		||||
    /* All points lie on a single line -- any decent normal will do */
 | 
			
		||||
    norm[0] = norm[1] = norm[2] = 0;
 | 
			
		||||
    norm[LongAxis(d1)] = 1;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void CheckOrientation( GLUtesselator *tess )
 | 
			
		||||
{
 | 
			
		||||
  GLdouble area;
 | 
			
		||||
  GLUface *f, *fHead = &tess->mesh->fHead;
 | 
			
		||||
  GLUvertex *v, *vHead = &tess->mesh->vHead;
 | 
			
		||||
  GLUhalfEdge *e;
 | 
			
		||||
 | 
			
		||||
  /* When we compute the normal automatically, we choose the orientation
 | 
			
		||||
   * so that the sum of the signed areas of all contours is non-negative.
 | 
			
		||||
   */
 | 
			
		||||
  area = 0;
 | 
			
		||||
  for( f = fHead->next; f != fHead; f = f->next ) {
 | 
			
		||||
    e = f->anEdge;
 | 
			
		||||
    if( e->winding <= 0 ) continue;
 | 
			
		||||
    do {
 | 
			
		||||
      area += (e->Org->s - e->Dst->s) * (e->Org->t + e->Dst->t);
 | 
			
		||||
      e = e->Lnext;
 | 
			
		||||
    } while( e != f->anEdge );
 | 
			
		||||
  }
 | 
			
		||||
  if( area < 0 ) {
 | 
			
		||||
    /* Reverse the orientation by flipping all the t-coordinates */
 | 
			
		||||
    for( v = vHead->next; v != vHead; v = v->next ) {
 | 
			
		||||
      v->t = - v->t;
 | 
			
		||||
    }
 | 
			
		||||
    tess->tUnit[0] = - tess->tUnit[0];
 | 
			
		||||
    tess->tUnit[1] = - tess->tUnit[1];
 | 
			
		||||
    tess->tUnit[2] = - tess->tUnit[2];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef FOR_TRITE_TEST_PROGRAM
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
extern int RandomSweep;
 | 
			
		||||
#define S_UNIT_X	(RandomSweep ? (2*drand48()-1) : 1.0)
 | 
			
		||||
#define S_UNIT_Y	(RandomSweep ? (2*drand48()-1) : 0.0)
 | 
			
		||||
#else
 | 
			
		||||
#if defined(SLANTED_SWEEP)
 | 
			
		||||
/* The "feature merging" is not intended to be complete.  There are
 | 
			
		||||
 * special cases where edges are nearly parallel to the sweep line
 | 
			
		||||
 * which are not implemented.  The algorithm should still behave
 | 
			
		||||
 * robustly (ie. produce a reasonable tesselation) in the presence
 | 
			
		||||
 * of such edges, however it may miss features which could have been
 | 
			
		||||
 * merged.  We could minimize this effect by choosing the sweep line
 | 
			
		||||
 * direction to be something unusual (ie. not parallel to one of the
 | 
			
		||||
 * coordinate axes).
 | 
			
		||||
 */
 | 
			
		||||
#define S_UNIT_X	0.50941539564955385	/* Pre-normalized */
 | 
			
		||||
#define S_UNIT_Y	0.86052074622010633
 | 
			
		||||
#else
 | 
			
		||||
#define S_UNIT_X	1.0
 | 
			
		||||
#define S_UNIT_Y	0.0
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Determine the polygon normal and project vertices onto the plane
 | 
			
		||||
 * of the polygon.
 | 
			
		||||
 */
 | 
			
		||||
void __gl_projectPolygon( GLUtesselator *tess )
 | 
			
		||||
{
 | 
			
		||||
  GLUvertex *v, *vHead = &tess->mesh->vHead;
 | 
			
		||||
  GLdouble norm[3];
 | 
			
		||||
  GLdouble *sUnit, *tUnit;
 | 
			
		||||
  int i, computedNormal = FALSE;
 | 
			
		||||
 | 
			
		||||
  norm[0] = tess->normal[0];
 | 
			
		||||
  norm[1] = tess->normal[1];
 | 
			
		||||
  norm[2] = tess->normal[2];
 | 
			
		||||
  if( norm[0] == 0 && norm[1] == 0 && norm[2] == 0 ) {
 | 
			
		||||
    ComputeNormal( tess, norm );
 | 
			
		||||
    computedNormal = TRUE;
 | 
			
		||||
  }
 | 
			
		||||
  sUnit = tess->sUnit;
 | 
			
		||||
  tUnit = tess->tUnit;
 | 
			
		||||
  i = LongAxis( norm );
 | 
			
		||||
 | 
			
		||||
#if defined(FOR_TRITE_TEST_PROGRAM) || defined(TRUE_PROJECT)
 | 
			
		||||
  /* Choose the initial sUnit vector to be approximately perpendicular
 | 
			
		||||
   * to the normal.
 | 
			
		||||
   */
 | 
			
		||||
  Normalize( norm );
 | 
			
		||||
 | 
			
		||||
  sUnit[i] = 0;
 | 
			
		||||
  sUnit[(i+1)%3] = S_UNIT_X;
 | 
			
		||||
  sUnit[(i+2)%3] = S_UNIT_Y;
 | 
			
		||||
 | 
			
		||||
  /* Now make it exactly perpendicular */
 | 
			
		||||
  w = Dot( sUnit, norm );
 | 
			
		||||
  sUnit[0] -= w * norm[0];
 | 
			
		||||
  sUnit[1] -= w * norm[1];
 | 
			
		||||
  sUnit[2] -= w * norm[2];
 | 
			
		||||
  Normalize( sUnit );
 | 
			
		||||
 | 
			
		||||
  /* Choose tUnit so that (sUnit,tUnit,norm) form a right-handed frame */
 | 
			
		||||
  tUnit[0] = norm[1]*sUnit[2] - norm[2]*sUnit[1];
 | 
			
		||||
  tUnit[1] = norm[2]*sUnit[0] - norm[0]*sUnit[2];
 | 
			
		||||
  tUnit[2] = norm[0]*sUnit[1] - norm[1]*sUnit[0];
 | 
			
		||||
  Normalize( tUnit );
 | 
			
		||||
#else
 | 
			
		||||
  /* Project perpendicular to a coordinate axis -- better numerically */
 | 
			
		||||
  sUnit[i] = 0;
 | 
			
		||||
  sUnit[(i+1)%3] = S_UNIT_X;
 | 
			
		||||
  sUnit[(i+2)%3] = S_UNIT_Y;
 | 
			
		||||
 | 
			
		||||
  tUnit[i] = 0;
 | 
			
		||||
  tUnit[(i+1)%3] = (norm[i] > 0) ? -S_UNIT_Y : S_UNIT_Y;
 | 
			
		||||
  tUnit[(i+2)%3] = (norm[i] > 0) ? S_UNIT_X : -S_UNIT_X;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  /* Project the vertices onto the sweep plane */
 | 
			
		||||
  for( v = vHead->next; v != vHead; v = v->next ) {
 | 
			
		||||
    v->s = Dot( v->coords, sUnit );
 | 
			
		||||
    v->t = Dot( v->coords, tUnit );
 | 
			
		||||
  }
 | 
			
		||||
  if( computedNormal ) {
 | 
			
		||||
    CheckOrientation( tess );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,46 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
** Author: Eric Veach, July 1994.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __normal_h_
 | 
			
		||||
#define __normal_h_
 | 
			
		||||
 | 
			
		||||
#include "tess.h"
 | 
			
		||||
#include "tesselator.h"
 | 
			
		||||
 | 
			
		||||
/* __gl_projectPolygon( tess ) determines the polygon normal
 | 
			
		||||
 * and project vertices onto the plane of the polygon.
 | 
			
		||||
 */
 | 
			
		||||
void __gl_projectPolygon( GLUtesselator *tess );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,256 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
** Author: Eric Veach, July 1994.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include "priorityq-heap.h"
 | 
			
		||||
#include "memalloc.h"
 | 
			
		||||
 | 
			
		||||
#define INIT_SIZE	32
 | 
			
		||||
 | 
			
		||||
#ifndef TRUE
 | 
			
		||||
#define TRUE 1
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef FALSE
 | 
			
		||||
#define FALSE 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef FOR_TRITE_TEST_PROGRAM
 | 
			
		||||
#define LEQ(x,y)	(*pq->leq)(x,y)
 | 
			
		||||
#else
 | 
			
		||||
/* Violates modularity, but a little faster */
 | 
			
		||||
#include "geom.h"
 | 
			
		||||
#define LEQ(x,y)	VertLeq((GLUvertex *)x, (GLUvertex *)y)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* really __gl_pqHeapNewPriorityQ */
 | 
			
		||||
PriorityQ *pqNewPriorityQ( int (*leq)(PQkey key1, PQkey key2) )
 | 
			
		||||
{
 | 
			
		||||
  PriorityQ *pq = (PriorityQ *)memAlloc( sizeof( PriorityQ ));
 | 
			
		||||
  if (pq == NULL) return NULL;
 | 
			
		||||
 | 
			
		||||
  pq->size = 0;
 | 
			
		||||
  pq->max = INIT_SIZE;
 | 
			
		||||
  pq->nodes = (PQnode *)memAlloc( (INIT_SIZE + 1) * sizeof(pq->nodes[0]) );
 | 
			
		||||
  if (pq->nodes == NULL) {
 | 
			
		||||
     memFree(pq);
 | 
			
		||||
     return NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  pq->handles = (PQhandleElem *)memAlloc( (INIT_SIZE + 1) * sizeof(pq->handles[0]) );
 | 
			
		||||
  if (pq->handles == NULL) {
 | 
			
		||||
     memFree(pq->nodes);
 | 
			
		||||
     memFree(pq);
 | 
			
		||||
     return NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  pq->initialized = FALSE;
 | 
			
		||||
  pq->freeList = 0;
 | 
			
		||||
  pq->leq = leq;
 | 
			
		||||
 | 
			
		||||
  pq->nodes[1].handle = 1;	/* so that Minimum() returns NULL */
 | 
			
		||||
  pq->handles[1].key = NULL;
 | 
			
		||||
  return pq;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* really __gl_pqHeapDeletePriorityQ */
 | 
			
		||||
void pqDeletePriorityQ( PriorityQ *pq )
 | 
			
		||||
{
 | 
			
		||||
  memFree( pq->handles );
 | 
			
		||||
  memFree( pq->nodes );
 | 
			
		||||
  memFree( pq );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void FloatDown( PriorityQ *pq, long curr )
 | 
			
		||||
{
 | 
			
		||||
  PQnode *n = pq->nodes;
 | 
			
		||||
  PQhandleElem *h = pq->handles;
 | 
			
		||||
  PQhandle hCurr, hChild;
 | 
			
		||||
  long child;
 | 
			
		||||
 | 
			
		||||
  hCurr = n[curr].handle;
 | 
			
		||||
  for( ;; ) {
 | 
			
		||||
    child = curr << 1;
 | 
			
		||||
    if( child < pq->size && LEQ( h[n[child+1].handle].key,
 | 
			
		||||
				 h[n[child].handle].key )) {
 | 
			
		||||
      ++child;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    assert(child <= pq->max);
 | 
			
		||||
 | 
			
		||||
    hChild = n[child].handle;
 | 
			
		||||
    if( child > pq->size || LEQ( h[hCurr].key, h[hChild].key )) {
 | 
			
		||||
      n[curr].handle = hCurr;
 | 
			
		||||
      h[hCurr].node = curr;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    n[curr].handle = hChild;
 | 
			
		||||
    h[hChild].node = curr;
 | 
			
		||||
    curr = child;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void FloatUp( PriorityQ *pq, long curr )
 | 
			
		||||
{
 | 
			
		||||
  PQnode *n = pq->nodes;
 | 
			
		||||
  PQhandleElem *h = pq->handles;
 | 
			
		||||
  PQhandle hCurr, hParent;
 | 
			
		||||
  long parent;
 | 
			
		||||
 | 
			
		||||
  hCurr = n[curr].handle;
 | 
			
		||||
  for( ;; ) {
 | 
			
		||||
    parent = curr >> 1;
 | 
			
		||||
    hParent = n[parent].handle;
 | 
			
		||||
    if( parent == 0 || LEQ( h[hParent].key, h[hCurr].key )) {
 | 
			
		||||
      n[curr].handle = hCurr;
 | 
			
		||||
      h[hCurr].node = curr;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    n[curr].handle = hParent;
 | 
			
		||||
    h[hParent].node = curr;
 | 
			
		||||
    curr = parent;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* really __gl_pqHeapInit */
 | 
			
		||||
void pqInit( PriorityQ *pq )
 | 
			
		||||
{
 | 
			
		||||
  long i;
 | 
			
		||||
 | 
			
		||||
  /* This method of building a heap is O(n), rather than O(n lg n). */
 | 
			
		||||
 | 
			
		||||
  for( i = pq->size; i >= 1; --i ) {
 | 
			
		||||
    FloatDown( pq, i );
 | 
			
		||||
  }
 | 
			
		||||
  pq->initialized = TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* really __gl_pqHeapInsert */
 | 
			
		||||
/* returns LONG_MAX iff out of memory */
 | 
			
		||||
PQhandle pqInsert( PriorityQ *pq, PQkey keyNew )
 | 
			
		||||
{
 | 
			
		||||
  long curr;
 | 
			
		||||
  PQhandle free_handle;
 | 
			
		||||
 | 
			
		||||
  curr = ++ pq->size;
 | 
			
		||||
  if( (curr*2) > pq->max ) {
 | 
			
		||||
    PQnode *saveNodes= pq->nodes;
 | 
			
		||||
    PQhandleElem *saveHandles= pq->handles;
 | 
			
		||||
 | 
			
		||||
    /* If the heap overflows, double its size. */
 | 
			
		||||
    pq->max <<= 1;
 | 
			
		||||
    pq->nodes = (PQnode *)memRealloc( pq->nodes, 
 | 
			
		||||
				     (size_t) 
 | 
			
		||||
				     ((pq->max + 1) * sizeof( pq->nodes[0] )));
 | 
			
		||||
    if (pq->nodes == NULL) {
 | 
			
		||||
       pq->nodes = saveNodes;	/* restore ptr to free upon return */
 | 
			
		||||
       return LONG_MAX;
 | 
			
		||||
    }
 | 
			
		||||
    pq->handles = (PQhandleElem *)memRealloc( pq->handles,
 | 
			
		||||
			                     (size_t)
 | 
			
		||||
			                      ((pq->max + 1) * 
 | 
			
		||||
					       sizeof( pq->handles[0] )));
 | 
			
		||||
    if (pq->handles == NULL) {
 | 
			
		||||
       pq->handles = saveHandles; /* restore ptr to free upon return */
 | 
			
		||||
       return LONG_MAX;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if( pq->freeList == 0 ) {
 | 
			
		||||
    free_handle = curr;
 | 
			
		||||
  } else {
 | 
			
		||||
    free_handle = pq->freeList;
 | 
			
		||||
    pq->freeList = pq->handles[free_handle].node;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  pq->nodes[curr].handle = free_handle;
 | 
			
		||||
  pq->handles[free_handle].node = curr;
 | 
			
		||||
  pq->handles[free_handle].key = keyNew;
 | 
			
		||||
 | 
			
		||||
  if( pq->initialized ) {
 | 
			
		||||
    FloatUp( pq, curr );
 | 
			
		||||
  }
 | 
			
		||||
  assert(free_handle != LONG_MAX);
 | 
			
		||||
  return free_handle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* really __gl_pqHeapExtractMin */
 | 
			
		||||
PQkey pqExtractMin( PriorityQ *pq )
 | 
			
		||||
{
 | 
			
		||||
  PQnode *n = pq->nodes;
 | 
			
		||||
  PQhandleElem *h = pq->handles;
 | 
			
		||||
  PQhandle hMin = n[1].handle;
 | 
			
		||||
  PQkey min = h[hMin].key;
 | 
			
		||||
 | 
			
		||||
  if( pq->size > 0 ) {
 | 
			
		||||
    n[1].handle = n[pq->size].handle;
 | 
			
		||||
    h[n[1].handle].node = 1;
 | 
			
		||||
 | 
			
		||||
    h[hMin].key = NULL;
 | 
			
		||||
    h[hMin].node = pq->freeList;
 | 
			
		||||
    pq->freeList = hMin;
 | 
			
		||||
 | 
			
		||||
    if( -- pq->size > 0 ) {
 | 
			
		||||
      FloatDown( pq, 1 );
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return min;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* really __gl_pqHeapDelete */
 | 
			
		||||
void pqDelete( PriorityQ *pq, PQhandle hCurr )
 | 
			
		||||
{
 | 
			
		||||
  PQnode *n = pq->nodes;
 | 
			
		||||
  PQhandleElem *h = pq->handles;
 | 
			
		||||
  long curr;
 | 
			
		||||
 | 
			
		||||
  assert( hCurr >= 1 && hCurr <= pq->max && h[hCurr].key != NULL );
 | 
			
		||||
 | 
			
		||||
  curr = h[hCurr].node;
 | 
			
		||||
  n[curr].handle = n[pq->size].handle;
 | 
			
		||||
  h[n[curr].handle].node = curr;
 | 
			
		||||
 | 
			
		||||
  if( curr <= -- pq->size ) {
 | 
			
		||||
    if( curr <= 1 || LEQ( h[n[curr>>1].handle].key, h[n[curr].handle].key )) {
 | 
			
		||||
      FloatDown( pq, curr );
 | 
			
		||||
    } else {
 | 
			
		||||
      FloatUp( pq, curr );
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  h[hCurr].key = NULL;
 | 
			
		||||
  h[hCurr].node = pq->freeList;
 | 
			
		||||
  pq->freeList = hCurr;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,107 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
** Author: Eric Veach, July 1994.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __priorityq_heap_h_
 | 
			
		||||
#define __priorityq_heap_h_
 | 
			
		||||
 | 
			
		||||
/* Use #define's so that another heap implementation can use this one */
 | 
			
		||||
 | 
			
		||||
#define PQkey			PQHeapKey
 | 
			
		||||
#define PQhandle		PQHeapHandle
 | 
			
		||||
#define PriorityQ		PriorityQHeap
 | 
			
		||||
 | 
			
		||||
#define pqNewPriorityQ(leq)	__gl_pqHeapNewPriorityQ(leq)
 | 
			
		||||
#define pqDeletePriorityQ(pq)	__gl_pqHeapDeletePriorityQ(pq)
 | 
			
		||||
 | 
			
		||||
/* The basic operations are insertion of a new key (pqInsert),
 | 
			
		||||
 * and examination/extraction of a key whose value is minimum
 | 
			
		||||
 * (pqMinimum/pqExtractMin).  Deletion is also allowed (pqDelete);
 | 
			
		||||
 * for this purpose pqInsert returns a "handle" which is supplied
 | 
			
		||||
 * as the argument.
 | 
			
		||||
 *
 | 
			
		||||
 * An initial heap may be created efficiently by calling pqInsert
 | 
			
		||||
 * repeatedly, then calling pqInit.  In any case pqInit must be called
 | 
			
		||||
 * before any operations other than pqInsert are used.
 | 
			
		||||
 *
 | 
			
		||||
 * If the heap is empty, pqMinimum/pqExtractMin will return a NULL key.
 | 
			
		||||
 * This may also be tested with pqIsEmpty.
 | 
			
		||||
 */
 | 
			
		||||
#define pqInit(pq)		__gl_pqHeapInit(pq)
 | 
			
		||||
#define pqInsert(pq,key)	__gl_pqHeapInsert(pq,key)
 | 
			
		||||
#define pqMinimum(pq)		__gl_pqHeapMinimum(pq)
 | 
			
		||||
#define pqExtractMin(pq)	__gl_pqHeapExtractMin(pq)
 | 
			
		||||
#define pqDelete(pq,handle)	__gl_pqHeapDelete(pq,handle)
 | 
			
		||||
#define pqIsEmpty(pq)		__gl_pqHeapIsEmpty(pq)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Since we support deletion the data structure is a little more
 | 
			
		||||
 * complicated than an ordinary heap.  "nodes" is the heap itself;
 | 
			
		||||
 * active nodes are stored in the range 1..pq->size.  When the
 | 
			
		||||
 * heap exceeds its allocated size (pq->max), its size doubles.
 | 
			
		||||
 * The children of node i are nodes 2i and 2i+1.
 | 
			
		||||
 *
 | 
			
		||||
 * Each node stores an index into an array "handles".  Each handle
 | 
			
		||||
 * stores a key, plus a pointer back to the node which currently
 | 
			
		||||
 * represents that key (ie. nodes[handles[i].node].handle == i).
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
typedef void *PQkey;
 | 
			
		||||
typedef long PQhandle;
 | 
			
		||||
typedef struct PriorityQ PriorityQ;
 | 
			
		||||
 | 
			
		||||
typedef struct { PQhandle handle; } PQnode;
 | 
			
		||||
typedef struct { PQkey key; PQhandle node; } PQhandleElem;
 | 
			
		||||
 | 
			
		||||
struct PriorityQ {
 | 
			
		||||
  PQnode	*nodes;
 | 
			
		||||
  PQhandleElem	*handles;
 | 
			
		||||
  long		size, max;
 | 
			
		||||
  PQhandle	freeList;
 | 
			
		||||
  int		initialized;
 | 
			
		||||
  int		(*leq)(PQkey key1, PQkey key2);
 | 
			
		||||
};
 | 
			
		||||
  
 | 
			
		||||
PriorityQ	*pqNewPriorityQ( int (*leq)(PQkey key1, PQkey key2) );
 | 
			
		||||
void		pqDeletePriorityQ( PriorityQ *pq );
 | 
			
		||||
 | 
			
		||||
void		pqInit( PriorityQ *pq );
 | 
			
		||||
PQhandle	pqInsert( PriorityQ *pq, PQkey key );
 | 
			
		||||
PQkey		pqExtractMin( PriorityQ *pq );
 | 
			
		||||
void		pqDelete( PriorityQ *pq, PQhandle handle );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define __gl_pqHeapMinimum(pq)	((pq)->handles[(pq)->nodes[1].handle].key)
 | 
			
		||||
#define __gl_pqHeapIsEmpty(pq)	((pq)->size == 0)
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,117 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
** Author: Eric Veach, July 1994.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __priorityq_sort_h_
 | 
			
		||||
#define __priorityq_sort_h_
 | 
			
		||||
 | 
			
		||||
#include "priorityq-heap.h"
 | 
			
		||||
 | 
			
		||||
#undef PQkey
 | 
			
		||||
#undef PQhandle
 | 
			
		||||
#undef PriorityQ
 | 
			
		||||
#undef pqNewPriorityQ
 | 
			
		||||
#undef pqDeletePriorityQ
 | 
			
		||||
#undef pqInit
 | 
			
		||||
#undef pqInsert
 | 
			
		||||
#undef pqMinimum
 | 
			
		||||
#undef pqExtractMin
 | 
			
		||||
#undef pqDelete
 | 
			
		||||
#undef pqIsEmpty
 | 
			
		||||
 | 
			
		||||
/* Use #define's so that another heap implementation can use this one */
 | 
			
		||||
 | 
			
		||||
#define PQkey			PQSortKey
 | 
			
		||||
#define PQhandle		PQSortHandle
 | 
			
		||||
#define PriorityQ		PriorityQSort
 | 
			
		||||
 | 
			
		||||
#define pqNewPriorityQ(leq)	__gl_pqSortNewPriorityQ(leq)
 | 
			
		||||
#define pqDeletePriorityQ(pq)	__gl_pqSortDeletePriorityQ(pq)
 | 
			
		||||
 | 
			
		||||
/* The basic operations are insertion of a new key (pqInsert),
 | 
			
		||||
 * and examination/extraction of a key whose value is minimum
 | 
			
		||||
 * (pqMinimum/pqExtractMin).  Deletion is also allowed (pqDelete);
 | 
			
		||||
 * for this purpose pqInsert returns a "handle" which is supplied
 | 
			
		||||
 * as the argument.
 | 
			
		||||
 *
 | 
			
		||||
 * An initial heap may be created efficiently by calling pqInsert
 | 
			
		||||
 * repeatedly, then calling pqInit.  In any case pqInit must be called
 | 
			
		||||
 * before any operations other than pqInsert are used.
 | 
			
		||||
 *
 | 
			
		||||
 * If the heap is empty, pqMinimum/pqExtractMin will return a NULL key.
 | 
			
		||||
 * This may also be tested with pqIsEmpty.
 | 
			
		||||
 */
 | 
			
		||||
#define pqInit(pq)		__gl_pqSortInit(pq)
 | 
			
		||||
#define pqInsert(pq,key)	__gl_pqSortInsert(pq,key)
 | 
			
		||||
#define pqMinimum(pq)		__gl_pqSortMinimum(pq)
 | 
			
		||||
#define pqExtractMin(pq)	__gl_pqSortExtractMin(pq)
 | 
			
		||||
#define pqDelete(pq,handle)	__gl_pqSortDelete(pq,handle)
 | 
			
		||||
#define pqIsEmpty(pq)		__gl_pqSortIsEmpty(pq)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Since we support deletion the data structure is a little more
 | 
			
		||||
 * complicated than an ordinary heap.  "nodes" is the heap itself;
 | 
			
		||||
 * active nodes are stored in the range 1..pq->size.  When the
 | 
			
		||||
 * heap exceeds its allocated size (pq->max), its size doubles.
 | 
			
		||||
 * The children of node i are nodes 2i and 2i+1.
 | 
			
		||||
 *
 | 
			
		||||
 * Each node stores an index into an array "handles".  Each handle
 | 
			
		||||
 * stores a key, plus a pointer back to the node which currently
 | 
			
		||||
 * represents that key (ie. nodes[handles[i].node].handle == i).
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
typedef PQHeapKey PQkey;
 | 
			
		||||
typedef PQHeapHandle PQhandle;
 | 
			
		||||
typedef struct PriorityQ PriorityQ;
 | 
			
		||||
 | 
			
		||||
struct PriorityQ {
 | 
			
		||||
  PriorityQHeap	*heap;
 | 
			
		||||
  PQkey		*keys;
 | 
			
		||||
  PQkey		**order;
 | 
			
		||||
  PQhandle	size, max;
 | 
			
		||||
  int		initialized;
 | 
			
		||||
  int		(*leq)(PQkey key1, PQkey key2);
 | 
			
		||||
};
 | 
			
		||||
  
 | 
			
		||||
PriorityQ	*pqNewPriorityQ( int (*leq)(PQkey key1, PQkey key2) );
 | 
			
		||||
void		pqDeletePriorityQ( PriorityQ *pq );
 | 
			
		||||
 | 
			
		||||
int		pqInit( PriorityQ *pq );
 | 
			
		||||
PQhandle	pqInsert( PriorityQ *pq, PQkey key );
 | 
			
		||||
PQkey		pqExtractMin( PriorityQ *pq );
 | 
			
		||||
void		pqDelete( PriorityQ *pq, PQhandle handle );
 | 
			
		||||
 | 
			
		||||
PQkey		pqMinimum( PriorityQ *pq );
 | 
			
		||||
int		pqIsEmpty( PriorityQ *pq );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,261 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
** Author: Eric Veach, July 1994.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "gluos.h"
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <limits.h>		/* LONG_MAX */
 | 
			
		||||
#include "memalloc.h"
 | 
			
		||||
 | 
			
		||||
/* Include all the code for the regular heap-based queue here. */
 | 
			
		||||
 | 
			
		||||
#include "priorityq-heap.c"
 | 
			
		||||
 | 
			
		||||
/* Now redefine all the function names to map to their "Sort" versions. */
 | 
			
		||||
 | 
			
		||||
#include "priorityq-sort.h"
 | 
			
		||||
 | 
			
		||||
/* really __gl_pqSortNewPriorityQ */
 | 
			
		||||
PriorityQ *pqNewPriorityQ( int (*leq)(PQkey key1, PQkey key2) )
 | 
			
		||||
{
 | 
			
		||||
  PriorityQ *pq = (PriorityQ *)memAlloc( sizeof( PriorityQ ));
 | 
			
		||||
  if (pq == NULL) return NULL;
 | 
			
		||||
 | 
			
		||||
  pq->heap = __gl_pqHeapNewPriorityQ( leq );
 | 
			
		||||
  if (pq->heap == NULL) {
 | 
			
		||||
     memFree(pq);
 | 
			
		||||
     return NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  pq->keys = (PQHeapKey *)memAlloc( INIT_SIZE * sizeof(pq->keys[0]) );
 | 
			
		||||
  if (pq->keys == NULL) {
 | 
			
		||||
     __gl_pqHeapDeletePriorityQ(pq->heap);
 | 
			
		||||
     memFree(pq);
 | 
			
		||||
     return NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  pq->order = NULL;
 | 
			
		||||
  pq->size = 0;
 | 
			
		||||
  pq->max = INIT_SIZE;
 | 
			
		||||
  pq->initialized = FALSE;
 | 
			
		||||
  pq->leq = leq;
 | 
			
		||||
  return pq;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* really __gl_pqSortDeletePriorityQ */
 | 
			
		||||
void pqDeletePriorityQ( PriorityQ *pq )
 | 
			
		||||
{
 | 
			
		||||
  assert(pq != NULL); 
 | 
			
		||||
  if (pq->heap != NULL) __gl_pqHeapDeletePriorityQ( pq->heap );
 | 
			
		||||
  if (pq->order != NULL) memFree( pq->order );
 | 
			
		||||
  if (pq->keys != NULL) memFree( pq->keys );
 | 
			
		||||
  memFree( pq );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define LT(x,y)		(! LEQ(y,x))
 | 
			
		||||
#define GT(x,y)		(! LEQ(x,y))
 | 
			
		||||
#define Swap(a,b)	do{PQkey *tmp = *a; *a = *b; *b = tmp;}while(0)
 | 
			
		||||
 | 
			
		||||
/* really __gl_pqSortInit */
 | 
			
		||||
int pqInit( PriorityQ *pq )
 | 
			
		||||
{
 | 
			
		||||
  PQkey **p, **r, **i, **j, *piv;
 | 
			
		||||
  struct { PQkey **p, **r; } Stack[50], *top = Stack;
 | 
			
		||||
  unsigned long seed = 2016473283;
 | 
			
		||||
 | 
			
		||||
  /* Create an array of indirect pointers to the keys, so that we
 | 
			
		||||
   * the handles we have returned are still valid.
 | 
			
		||||
   */
 | 
			
		||||
/*
 | 
			
		||||
  pq->order = (PQHeapKey **)memAlloc( (size_t)
 | 
			
		||||
                                  (pq->size * sizeof(pq->order[0])) );
 | 
			
		||||
*/
 | 
			
		||||
  pq->order = (PQHeapKey **)memAlloc( (size_t)
 | 
			
		||||
                                  ((pq->size+1) * sizeof(pq->order[0])) );
 | 
			
		||||
/* the previous line is a patch to compensate for the fact that IBM */
 | 
			
		||||
/* machines return a null on a malloc of zero bytes (unlike SGI),   */
 | 
			
		||||
/* so we have to put in this defense to guard against a memory      */
 | 
			
		||||
/* fault four lines down. from fossum@austin.ibm.com.               */
 | 
			
		||||
  if (pq->order == NULL) return 0;
 | 
			
		||||
 | 
			
		||||
  p = pq->order;
 | 
			
		||||
  r = p + pq->size - 1;
 | 
			
		||||
  for( piv = pq->keys, i = p; i <= r; ++piv, ++i ) {
 | 
			
		||||
    *i = piv;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Sort the indirect pointers in descending order,
 | 
			
		||||
   * using randomized Quicksort
 | 
			
		||||
   */
 | 
			
		||||
  top->p = p; top->r = r; ++top;
 | 
			
		||||
  while( --top >= Stack ) {
 | 
			
		||||
    p = top->p;
 | 
			
		||||
    r = top->r;
 | 
			
		||||
    while( r > p + 10 ) {
 | 
			
		||||
      seed = seed * 1539415821 + 1;
 | 
			
		||||
      i = p + seed % (r - p + 1);
 | 
			
		||||
      piv = *i;
 | 
			
		||||
      *i = *p;
 | 
			
		||||
      *p = piv;
 | 
			
		||||
      i = p - 1;
 | 
			
		||||
      j = r + 1;
 | 
			
		||||
      do {
 | 
			
		||||
	do { ++i; } while( GT( **i, *piv ));
 | 
			
		||||
	do { --j; } while( LT( **j, *piv ));
 | 
			
		||||
	Swap( i, j );
 | 
			
		||||
      } while( i < j );
 | 
			
		||||
      Swap( i, j );	/* Undo last swap */
 | 
			
		||||
      if( i - p < r - j ) {
 | 
			
		||||
	top->p = j+1; top->r = r; ++top;
 | 
			
		||||
	r = i-1;
 | 
			
		||||
      } else {
 | 
			
		||||
	top->p = p; top->r = i-1; ++top;
 | 
			
		||||
	p = j+1;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    /* Insertion sort small lists */
 | 
			
		||||
    for( i = p+1; i <= r; ++i ) {
 | 
			
		||||
      piv = *i;
 | 
			
		||||
      for( j = i; j > p && LT( **(j-1), *piv ); --j ) {
 | 
			
		||||
	*j = *(j-1);
 | 
			
		||||
      }
 | 
			
		||||
      *j = piv;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  pq->max = pq->size;
 | 
			
		||||
  pq->initialized = TRUE;
 | 
			
		||||
  __gl_pqHeapInit( pq->heap );	/* always succeeds */
 | 
			
		||||
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
  p = pq->order;
 | 
			
		||||
  r = p + pq->size - 1;
 | 
			
		||||
  for( i = p; i < r; ++i ) {
 | 
			
		||||
    assert( LEQ( **(i+1), **i ));
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* really __gl_pqSortInsert */
 | 
			
		||||
/* returns LONG_MAX iff out of memory */ 
 | 
			
		||||
PQhandle pqInsert( PriorityQ *pq, PQkey keyNew )
 | 
			
		||||
{
 | 
			
		||||
  long curr;
 | 
			
		||||
 | 
			
		||||
  if( pq->initialized ) {
 | 
			
		||||
    return __gl_pqHeapInsert( pq->heap, keyNew );
 | 
			
		||||
  }
 | 
			
		||||
  curr = pq->size;
 | 
			
		||||
  if( ++ pq->size >= pq->max ) {
 | 
			
		||||
    PQkey *saveKey= pq->keys;
 | 
			
		||||
 | 
			
		||||
    /* If the heap overflows, double its size. */
 | 
			
		||||
    pq->max <<= 1;
 | 
			
		||||
    pq->keys = (PQHeapKey *)memRealloc( pq->keys, 
 | 
			
		||||
	 	                        (size_t)
 | 
			
		||||
	                                 (pq->max * sizeof( pq->keys[0] )));
 | 
			
		||||
    if (pq->keys == NULL) {	
 | 
			
		||||
       pq->keys = saveKey;	/* restore ptr to free upon return */
 | 
			
		||||
       return LONG_MAX;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  assert(curr != LONG_MAX);	
 | 
			
		||||
  pq->keys[curr] = keyNew;
 | 
			
		||||
 | 
			
		||||
  /* Negative handles index the sorted array. */
 | 
			
		||||
  return -(curr+1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* really __gl_pqSortExtractMin */
 | 
			
		||||
PQkey pqExtractMin( PriorityQ *pq )
 | 
			
		||||
{
 | 
			
		||||
  PQkey sortMin, heapMin;
 | 
			
		||||
 | 
			
		||||
  if( pq->size == 0 ) {
 | 
			
		||||
    return __gl_pqHeapExtractMin( pq->heap );
 | 
			
		||||
  }
 | 
			
		||||
  sortMin = *(pq->order[pq->size-1]);
 | 
			
		||||
  if( ! __gl_pqHeapIsEmpty( pq->heap )) {
 | 
			
		||||
    heapMin = __gl_pqHeapMinimum( pq->heap );
 | 
			
		||||
    if( LEQ( heapMin, sortMin )) {
 | 
			
		||||
      return __gl_pqHeapExtractMin( pq->heap );
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  do {
 | 
			
		||||
    -- pq->size;
 | 
			
		||||
  } while( pq->size > 0 && *(pq->order[pq->size-1]) == NULL );
 | 
			
		||||
  return sortMin;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* really __gl_pqSortMinimum */
 | 
			
		||||
PQkey pqMinimum( PriorityQ *pq )
 | 
			
		||||
{
 | 
			
		||||
  PQkey sortMin, heapMin;
 | 
			
		||||
 | 
			
		||||
  if( pq->size == 0 ) {
 | 
			
		||||
    return __gl_pqHeapMinimum( pq->heap );
 | 
			
		||||
  }
 | 
			
		||||
  sortMin = *(pq->order[pq->size-1]);
 | 
			
		||||
  if( ! __gl_pqHeapIsEmpty( pq->heap )) {
 | 
			
		||||
    heapMin = __gl_pqHeapMinimum( pq->heap );
 | 
			
		||||
    if( LEQ( heapMin, sortMin )) {
 | 
			
		||||
      return heapMin;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return sortMin;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* really __gl_pqSortIsEmpty */
 | 
			
		||||
int pqIsEmpty( PriorityQ *pq )
 | 
			
		||||
{
 | 
			
		||||
  return (pq->size == 0) && __gl_pqHeapIsEmpty( pq->heap );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* really __gl_pqSortDelete */
 | 
			
		||||
void pqDelete( PriorityQ *pq, PQhandle curr )
 | 
			
		||||
{
 | 
			
		||||
  if( curr >= 0 ) {
 | 
			
		||||
    __gl_pqHeapDelete( pq->heap, curr );
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  curr = -(curr+1);
 | 
			
		||||
  assert( curr < pq->max && pq->keys[curr] != NULL );
 | 
			
		||||
 | 
			
		||||
  pq->keys[curr] = NULL;
 | 
			
		||||
  while( pq->size > 0 && *(pq->order[pq->size-1]) == NULL ) {
 | 
			
		||||
    -- pq->size;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,117 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
** Author: Eric Veach, July 1994.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __priorityq_sort_h_
 | 
			
		||||
#define __priorityq_sort_h_
 | 
			
		||||
 | 
			
		||||
#include "priorityq-heap.h"
 | 
			
		||||
 | 
			
		||||
#undef PQkey
 | 
			
		||||
#undef PQhandle
 | 
			
		||||
#undef PriorityQ
 | 
			
		||||
#undef pqNewPriorityQ
 | 
			
		||||
#undef pqDeletePriorityQ
 | 
			
		||||
#undef pqInit
 | 
			
		||||
#undef pqInsert
 | 
			
		||||
#undef pqMinimum
 | 
			
		||||
#undef pqExtractMin
 | 
			
		||||
#undef pqDelete
 | 
			
		||||
#undef pqIsEmpty
 | 
			
		||||
 | 
			
		||||
/* Use #define's so that another heap implementation can use this one */
 | 
			
		||||
 | 
			
		||||
#define PQkey			PQSortKey
 | 
			
		||||
#define PQhandle		PQSortHandle
 | 
			
		||||
#define PriorityQ		PriorityQSort
 | 
			
		||||
 | 
			
		||||
#define pqNewPriorityQ(leq)	__gl_pqSortNewPriorityQ(leq)
 | 
			
		||||
#define pqDeletePriorityQ(pq)	__gl_pqSortDeletePriorityQ(pq)
 | 
			
		||||
 | 
			
		||||
/* The basic operations are insertion of a new key (pqInsert),
 | 
			
		||||
 * and examination/extraction of a key whose value is minimum
 | 
			
		||||
 * (pqMinimum/pqExtractMin).  Deletion is also allowed (pqDelete);
 | 
			
		||||
 * for this purpose pqInsert returns a "handle" which is supplied
 | 
			
		||||
 * as the argument.
 | 
			
		||||
 *
 | 
			
		||||
 * An initial heap may be created efficiently by calling pqInsert
 | 
			
		||||
 * repeatedly, then calling pqInit.  In any case pqInit must be called
 | 
			
		||||
 * before any operations other than pqInsert are used.
 | 
			
		||||
 *
 | 
			
		||||
 * If the heap is empty, pqMinimum/pqExtractMin will return a NULL key.
 | 
			
		||||
 * This may also be tested with pqIsEmpty.
 | 
			
		||||
 */
 | 
			
		||||
#define pqInit(pq)		__gl_pqSortInit(pq)
 | 
			
		||||
#define pqInsert(pq,key)	__gl_pqSortInsert(pq,key)
 | 
			
		||||
#define pqMinimum(pq)		__gl_pqSortMinimum(pq)
 | 
			
		||||
#define pqExtractMin(pq)	__gl_pqSortExtractMin(pq)
 | 
			
		||||
#define pqDelete(pq,handle)	__gl_pqSortDelete(pq,handle)
 | 
			
		||||
#define pqIsEmpty(pq)		__gl_pqSortIsEmpty(pq)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Since we support deletion the data structure is a little more
 | 
			
		||||
 * complicated than an ordinary heap.  "nodes" is the heap itself;
 | 
			
		||||
 * active nodes are stored in the range 1..pq->size.  When the
 | 
			
		||||
 * heap exceeds its allocated size (pq->max), its size doubles.
 | 
			
		||||
 * The children of node i are nodes 2i and 2i+1.
 | 
			
		||||
 *
 | 
			
		||||
 * Each node stores an index into an array "handles".  Each handle
 | 
			
		||||
 * stores a key, plus a pointer back to the node which currently
 | 
			
		||||
 * represents that key (ie. nodes[handles[i].node].handle == i).
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
typedef PQHeapKey PQkey;
 | 
			
		||||
typedef PQHeapHandle PQhandle;
 | 
			
		||||
typedef struct PriorityQ PriorityQ;
 | 
			
		||||
 | 
			
		||||
struct PriorityQ {
 | 
			
		||||
  PriorityQHeap	*heap;
 | 
			
		||||
  PQkey		*keys;
 | 
			
		||||
  PQkey		**order;
 | 
			
		||||
  PQhandle	size, max;
 | 
			
		||||
  int		initialized;
 | 
			
		||||
  int		(*leq)(PQkey key1, PQkey key2);
 | 
			
		||||
};
 | 
			
		||||
  
 | 
			
		||||
PriorityQ	*pqNewPriorityQ( int (*leq)(PQkey key1, PQkey key2) );
 | 
			
		||||
void		pqDeletePriorityQ( PriorityQ *pq );
 | 
			
		||||
 | 
			
		||||
int		pqInit( PriorityQ *pq );
 | 
			
		||||
PQhandle	pqInsert( PriorityQ *pq, PQkey key );
 | 
			
		||||
PQkey		pqExtractMin( PriorityQ *pq );
 | 
			
		||||
void		pqDelete( PriorityQ *pq, PQhandle handle );
 | 
			
		||||
 | 
			
		||||
PQkey		pqMinimum( PriorityQ *pq );
 | 
			
		||||
int		pqIsEmpty( PriorityQ *pq );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,502 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
** Author: Eric Veach, July 1994.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "gluos.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include "mesh.h"
 | 
			
		||||
#include "tess.h"
 | 
			
		||||
#include "render.h"
 | 
			
		||||
 | 
			
		||||
#ifndef TRUE
 | 
			
		||||
#define TRUE 1
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef FALSE
 | 
			
		||||
#define FALSE 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* This structure remembers the information we need about a primitive
 | 
			
		||||
 * to be able to render it later, once we have determined which
 | 
			
		||||
 * primitive is able to use the most triangles.
 | 
			
		||||
 */
 | 
			
		||||
struct FaceCount {
 | 
			
		||||
  long		size;		/* number of triangles used */
 | 
			
		||||
  GLUhalfEdge	*eStart;	/* edge where this primitive starts */
 | 
			
		||||
  void		(*render)(GLUtesselator *, GLUhalfEdge *, long);
 | 
			
		||||
                                /* routine to render this primitive */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct FaceCount MaximumFan( GLUhalfEdge *eOrig );
 | 
			
		||||
static struct FaceCount MaximumStrip( GLUhalfEdge *eOrig );
 | 
			
		||||
 | 
			
		||||
static void RenderFan( GLUtesselator *tess, GLUhalfEdge *eStart, long size );
 | 
			
		||||
static void RenderStrip( GLUtesselator *tess, GLUhalfEdge *eStart, long size );
 | 
			
		||||
static void RenderTriangle( GLUtesselator *tess, GLUhalfEdge *eStart,
 | 
			
		||||
			    long size );
 | 
			
		||||
 | 
			
		||||
static void RenderMaximumFaceGroup( GLUtesselator *tess, GLUface *fOrig );
 | 
			
		||||
static void RenderLonelyTriangles( GLUtesselator *tess, GLUface *head );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/************************ Strips and Fans decomposition ******************/
 | 
			
		||||
 | 
			
		||||
/* __gl_renderMesh( tess, mesh ) takes a mesh and breaks it into triangle
 | 
			
		||||
 * fans, strips, and separate triangles.  A substantial effort is made
 | 
			
		||||
 * to use as few rendering primitives as possible (ie. to make the fans
 | 
			
		||||
 * and strips as large as possible).
 | 
			
		||||
 *
 | 
			
		||||
 * The rendering output is provided as callbacks (see the api).
 | 
			
		||||
 */
 | 
			
		||||
void __gl_renderMesh( GLUtesselator *tess, GLUmesh *mesh )
 | 
			
		||||
{
 | 
			
		||||
  GLUface *f;
 | 
			
		||||
 | 
			
		||||
  /* Make a list of separate triangles so we can render them all at once */
 | 
			
		||||
  tess->lonelyTriList = NULL;
 | 
			
		||||
 | 
			
		||||
  for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) {
 | 
			
		||||
    f->marked = FALSE;
 | 
			
		||||
  }
 | 
			
		||||
  for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) {
 | 
			
		||||
 | 
			
		||||
    /* We examine all faces in an arbitrary order.  Whenever we find
 | 
			
		||||
     * an unprocessed face F, we output a group of faces including F
 | 
			
		||||
     * whose size is maximum.
 | 
			
		||||
     */
 | 
			
		||||
    if( f->inside && ! f->marked ) {
 | 
			
		||||
      RenderMaximumFaceGroup( tess, f );
 | 
			
		||||
      assert( f->marked );
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if( tess->lonelyTriList != NULL ) {
 | 
			
		||||
    RenderLonelyTriangles( tess, tess->lonelyTriList );
 | 
			
		||||
    tess->lonelyTriList = NULL;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void RenderMaximumFaceGroup( GLUtesselator *tess, GLUface *fOrig )
 | 
			
		||||
{
 | 
			
		||||
  /* We want to find the largest triangle fan or strip of unmarked faces
 | 
			
		||||
   * which includes the given face fOrig.  There are 3 possible fans
 | 
			
		||||
   * passing through fOrig (one centered at each vertex), and 3 possible
 | 
			
		||||
   * strips (one for each CCW permutation of the vertices).  Our strategy
 | 
			
		||||
   * is to try all of these, and take the primitive which uses the most
 | 
			
		||||
   * triangles (a greedy approach).
 | 
			
		||||
   */
 | 
			
		||||
  GLUhalfEdge *e = fOrig->anEdge;
 | 
			
		||||
  struct FaceCount max, newFace;
 | 
			
		||||
 | 
			
		||||
  max.size = 1;
 | 
			
		||||
  max.eStart = e;
 | 
			
		||||
  max.render = &RenderTriangle;
 | 
			
		||||
 | 
			
		||||
  if( ! tess->flagBoundary ) {
 | 
			
		||||
    newFace = MaximumFan( e ); if( newFace.size > max.size ) { max = newFace; }
 | 
			
		||||
    newFace = MaximumFan( e->Lnext ); if( newFace.size > max.size ) { max = newFace; }
 | 
			
		||||
    newFace = MaximumFan( e->Lprev ); if( newFace.size > max.size ) { max = newFace; }
 | 
			
		||||
 | 
			
		||||
    newFace = MaximumStrip( e ); if( newFace.size > max.size ) { max = newFace; }
 | 
			
		||||
    newFace = MaximumStrip( e->Lnext ); if( newFace.size > max.size ) { max = newFace; }
 | 
			
		||||
    newFace = MaximumStrip( e->Lprev ); if( newFace.size > max.size ) { max = newFace; }
 | 
			
		||||
  }
 | 
			
		||||
  (*(max.render))( tess, max.eStart, max.size );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Macros which keep track of faces we have marked temporarily, and allow
 | 
			
		||||
 * us to backtrack when necessary.  With triangle fans, this is not
 | 
			
		||||
 * really necessary, since the only awkward case is a loop of triangles
 | 
			
		||||
 * around a single origin vertex.  However with strips the situation is
 | 
			
		||||
 * more complicated, and we need a general tracking method like the
 | 
			
		||||
 * one here.
 | 
			
		||||
 */
 | 
			
		||||
#define Marked(f)	(! (f)->inside || (f)->marked)
 | 
			
		||||
 | 
			
		||||
#define AddToTrail(f,t)	((f)->trail = (t), (t) = (f), (f)->marked = TRUE)
 | 
			
		||||
 | 
			
		||||
#define FreeTrail(t)	do { \
 | 
			
		||||
			  while( (t) != NULL ) { \
 | 
			
		||||
			    (t)->marked = FALSE; t = (t)->trail; \
 | 
			
		||||
			  } \
 | 
			
		||||
			} while(0) /* absorb trailing semicolon */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static struct FaceCount MaximumFan( GLUhalfEdge *eOrig )
 | 
			
		||||
{
 | 
			
		||||
  /* eOrig->Lface is the face we want to render.  We want to find the size
 | 
			
		||||
   * of a maximal fan around eOrig->Org.  To do this we just walk around
 | 
			
		||||
   * the origin vertex as far as possible in both directions.
 | 
			
		||||
   */
 | 
			
		||||
  struct FaceCount newFace = { 0, NULL, &RenderFan };
 | 
			
		||||
  GLUface *trail = NULL;
 | 
			
		||||
  GLUhalfEdge *e;
 | 
			
		||||
 | 
			
		||||
  for( e = eOrig; ! Marked( e->Lface ); e = e->Onext ) {
 | 
			
		||||
    AddToTrail( e->Lface, trail );
 | 
			
		||||
    ++newFace.size;
 | 
			
		||||
  }
 | 
			
		||||
  for( e = eOrig; ! Marked( e->Rface ); e = e->Oprev ) {
 | 
			
		||||
    AddToTrail( e->Rface, trail );
 | 
			
		||||
    ++newFace.size;
 | 
			
		||||
  }
 | 
			
		||||
  newFace.eStart = e;
 | 
			
		||||
  /*LINTED*/
 | 
			
		||||
  FreeTrail( trail );
 | 
			
		||||
  return newFace;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define IsEven(n)	(((n) & 1) == 0)
 | 
			
		||||
 | 
			
		||||
static struct FaceCount MaximumStrip( GLUhalfEdge *eOrig )
 | 
			
		||||
{
 | 
			
		||||
  /* Here we are looking for a maximal strip that contains the vertices
 | 
			
		||||
   * eOrig->Org, eOrig->Dst, eOrig->Lnext->Dst (in that order or the
 | 
			
		||||
   * reverse, such that all triangles are oriented CCW).
 | 
			
		||||
   *
 | 
			
		||||
   * Again we walk forward and backward as far as possible.  However for
 | 
			
		||||
   * strips there is a twist: to get CCW orientations, there must be
 | 
			
		||||
   * an *even* number of triangles in the strip on one side of eOrig.
 | 
			
		||||
   * We walk the strip starting on a side with an even number of triangles;
 | 
			
		||||
   * if both side have an odd number, we are forced to shorten one side.
 | 
			
		||||
   */
 | 
			
		||||
  struct FaceCount newFace = { 0, NULL, &RenderStrip };
 | 
			
		||||
  long headSize = 0, tailSize = 0;
 | 
			
		||||
  GLUface *trail = NULL;
 | 
			
		||||
  GLUhalfEdge *e, *eTail, *eHead;
 | 
			
		||||
 | 
			
		||||
  for( e = eOrig; ! Marked( e->Lface ); ++tailSize, e = e->Onext ) {
 | 
			
		||||
    AddToTrail( e->Lface, trail );
 | 
			
		||||
    ++tailSize;
 | 
			
		||||
    e = e->Dprev;
 | 
			
		||||
    if( Marked( e->Lface )) break;
 | 
			
		||||
    AddToTrail( e->Lface, trail );
 | 
			
		||||
  }
 | 
			
		||||
  eTail = e;
 | 
			
		||||
 | 
			
		||||
  for( e = eOrig; ! Marked( e->Rface ); ++headSize, e = e->Dnext ) {
 | 
			
		||||
    AddToTrail( e->Rface, trail );
 | 
			
		||||
    ++headSize;
 | 
			
		||||
    e = e->Oprev;
 | 
			
		||||
    if( Marked( e->Rface )) break;
 | 
			
		||||
    AddToTrail( e->Rface, trail );
 | 
			
		||||
  }
 | 
			
		||||
  eHead = e;
 | 
			
		||||
 | 
			
		||||
  newFace.size = tailSize + headSize;
 | 
			
		||||
  if( IsEven( tailSize )) {
 | 
			
		||||
    newFace.eStart = eTail->Sym;
 | 
			
		||||
  } else if( IsEven( headSize )) {
 | 
			
		||||
    newFace.eStart = eHead;
 | 
			
		||||
  } else {
 | 
			
		||||
    /* Both sides have odd length, we must shorten one of them.  In fact,
 | 
			
		||||
     * we must start from eHead to guarantee inclusion of eOrig->Lface.
 | 
			
		||||
     */
 | 
			
		||||
    --newFace.size;
 | 
			
		||||
    newFace.eStart = eHead->Onext;
 | 
			
		||||
  }
 | 
			
		||||
  /*LINTED*/
 | 
			
		||||
  FreeTrail( trail );
 | 
			
		||||
  return newFace;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void RenderTriangle( GLUtesselator *tess, GLUhalfEdge *e, long size )
 | 
			
		||||
{
 | 
			
		||||
  /* Just add the triangle to a triangle list, so we can render all
 | 
			
		||||
   * the separate triangles at once.
 | 
			
		||||
   */
 | 
			
		||||
  assert( size == 1 );
 | 
			
		||||
  AddToTrail( e->Lface, tess->lonelyTriList );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void RenderLonelyTriangles( GLUtesselator *tess, GLUface *f )
 | 
			
		||||
{
 | 
			
		||||
  /* Now we render all the separate triangles which could not be
 | 
			
		||||
   * grouped into a triangle fan or strip.
 | 
			
		||||
   */
 | 
			
		||||
  GLUhalfEdge *e;
 | 
			
		||||
  int newState;
 | 
			
		||||
  int edgeState = -1;	/* force edge state output for first vertex */
 | 
			
		||||
 | 
			
		||||
  CALL_BEGIN_OR_BEGIN_DATA( GL_TRIANGLES );
 | 
			
		||||
 | 
			
		||||
  for( ; f != NULL; f = f->trail ) {
 | 
			
		||||
    /* Loop once for each edge (there will always be 3 edges) */
 | 
			
		||||
 | 
			
		||||
    e = f->anEdge;
 | 
			
		||||
    do {
 | 
			
		||||
      if( tess->flagBoundary ) {
 | 
			
		||||
	/* Set the "edge state" to TRUE just before we output the
 | 
			
		||||
	 * first vertex of each edge on the polygon boundary.
 | 
			
		||||
	 */
 | 
			
		||||
	newState = ! e->Rface->inside;
 | 
			
		||||
	if( edgeState != newState ) {
 | 
			
		||||
	  edgeState = newState;
 | 
			
		||||
          CALL_EDGE_FLAG_OR_EDGE_FLAG_DATA( edgeState );
 | 
			
		||||
	}
 | 
			
		||||
      }
 | 
			
		||||
      CALL_VERTEX_OR_VERTEX_DATA( e->Org->data );
 | 
			
		||||
 | 
			
		||||
      e = e->Lnext;
 | 
			
		||||
    } while( e != f->anEdge );
 | 
			
		||||
  }
 | 
			
		||||
  CALL_END_OR_END_DATA();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void RenderFan( GLUtesselator *tess, GLUhalfEdge *e, long size )
 | 
			
		||||
{
 | 
			
		||||
  /* Render as many CCW triangles as possible in a fan starting from
 | 
			
		||||
   * edge "e".  The fan *should* contain exactly "size" triangles
 | 
			
		||||
   * (otherwise we've goofed up somewhere).
 | 
			
		||||
   */
 | 
			
		||||
  CALL_BEGIN_OR_BEGIN_DATA( GL_TRIANGLE_FAN ); 
 | 
			
		||||
  CALL_VERTEX_OR_VERTEX_DATA( e->Org->data ); 
 | 
			
		||||
  CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data ); 
 | 
			
		||||
 | 
			
		||||
  while( ! Marked( e->Lface )) {
 | 
			
		||||
    e->Lface->marked = TRUE;
 | 
			
		||||
    --size;
 | 
			
		||||
    e = e->Onext;
 | 
			
		||||
    CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data ); 
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  assert( size == 0 );
 | 
			
		||||
  CALL_END_OR_END_DATA();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void RenderStrip( GLUtesselator *tess, GLUhalfEdge *e, long size )
 | 
			
		||||
{
 | 
			
		||||
  /* Render as many CCW triangles as possible in a strip starting from
 | 
			
		||||
   * edge "e".  The strip *should* contain exactly "size" triangles
 | 
			
		||||
   * (otherwise we've goofed up somewhere).
 | 
			
		||||
   */
 | 
			
		||||
  CALL_BEGIN_OR_BEGIN_DATA( GL_TRIANGLE_STRIP );
 | 
			
		||||
  CALL_VERTEX_OR_VERTEX_DATA( e->Org->data ); 
 | 
			
		||||
  CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data ); 
 | 
			
		||||
 | 
			
		||||
  while( ! Marked( e->Lface )) {
 | 
			
		||||
    e->Lface->marked = TRUE;
 | 
			
		||||
    --size;
 | 
			
		||||
    e = e->Dprev;
 | 
			
		||||
    CALL_VERTEX_OR_VERTEX_DATA( e->Org->data ); 
 | 
			
		||||
    if( Marked( e->Lface )) break;
 | 
			
		||||
 | 
			
		||||
    e->Lface->marked = TRUE;
 | 
			
		||||
    --size;
 | 
			
		||||
    e = e->Onext;
 | 
			
		||||
    CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data ); 
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  assert( size == 0 );
 | 
			
		||||
  CALL_END_OR_END_DATA();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/************************ Boundary contour decomposition ******************/
 | 
			
		||||
 | 
			
		||||
/* __gl_renderBoundary( tess, mesh ) takes a mesh, and outputs one
 | 
			
		||||
 * contour for each face marked "inside".  The rendering output is
 | 
			
		||||
 * provided as callbacks (see the api).
 | 
			
		||||
 */
 | 
			
		||||
void __gl_renderBoundary( GLUtesselator *tess, GLUmesh *mesh )
 | 
			
		||||
{
 | 
			
		||||
  GLUface *f;
 | 
			
		||||
  GLUhalfEdge *e;
 | 
			
		||||
 | 
			
		||||
  for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) {
 | 
			
		||||
    if( f->inside ) {
 | 
			
		||||
      CALL_BEGIN_OR_BEGIN_DATA( GL_LINE_LOOP );
 | 
			
		||||
      e = f->anEdge;
 | 
			
		||||
      do {
 | 
			
		||||
        CALL_VERTEX_OR_VERTEX_DATA( e->Org->data ); 
 | 
			
		||||
	e = e->Lnext;
 | 
			
		||||
      } while( e != f->anEdge );
 | 
			
		||||
      CALL_END_OR_END_DATA();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/************************ Quick-and-dirty decomposition ******************/
 | 
			
		||||
 | 
			
		||||
#define SIGN_INCONSISTENT 2
 | 
			
		||||
 | 
			
		||||
static int ComputeNormal( GLUtesselator *tess, GLdouble norm[3], int check )
 | 
			
		||||
/*
 | 
			
		||||
 * If check==FALSE, we compute the polygon normal and place it in norm[].
 | 
			
		||||
 * If check==TRUE, we check that each triangle in the fan from v0 has a
 | 
			
		||||
 * consistent orientation with respect to norm[].  If triangles are
 | 
			
		||||
 * consistently oriented CCW, return 1; if CW, return -1; if all triangles
 | 
			
		||||
 * are degenerate return 0; otherwise (no consistent orientation) return
 | 
			
		||||
 * SIGN_INCONSISTENT.
 | 
			
		||||
 */
 | 
			
		||||
{
 | 
			
		||||
  CachedVertex *v0 = tess->cache;
 | 
			
		||||
  CachedVertex *vn = v0 + tess->cacheCount;
 | 
			
		||||
  CachedVertex *vc;
 | 
			
		||||
  GLdouble dot, xc, yc, zc, xp, yp, zp, n[3];
 | 
			
		||||
  int sign = 0;
 | 
			
		||||
 | 
			
		||||
  /* Find the polygon normal.  It is important to get a reasonable
 | 
			
		||||
   * normal even when the polygon is self-intersecting (eg. a bowtie).
 | 
			
		||||
   * Otherwise, the computed normal could be very tiny, but perpendicular
 | 
			
		||||
   * to the true plane of the polygon due to numerical noise.  Then all
 | 
			
		||||
   * the triangles would appear to be degenerate and we would incorrectly
 | 
			
		||||
   * decompose the polygon as a fan (or simply not render it at all).
 | 
			
		||||
   *
 | 
			
		||||
   * We use a sum-of-triangles normal algorithm rather than the more
 | 
			
		||||
   * efficient sum-of-trapezoids method (used in CheckOrientation()
 | 
			
		||||
   * in normal.c).  This lets us explicitly reverse the signed area
 | 
			
		||||
   * of some triangles to get a reasonable normal in the self-intersecting
 | 
			
		||||
   * case.
 | 
			
		||||
   */
 | 
			
		||||
  if( ! check ) {
 | 
			
		||||
    norm[0] = norm[1] = norm[2] = 0.0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  vc = v0 + 1;
 | 
			
		||||
  xc = vc->coords[0] - v0->coords[0];
 | 
			
		||||
  yc = vc->coords[1] - v0->coords[1];
 | 
			
		||||
  zc = vc->coords[2] - v0->coords[2];
 | 
			
		||||
  while( ++vc < vn ) {
 | 
			
		||||
    xp = xc; yp = yc; zp = zc;
 | 
			
		||||
    xc = vc->coords[0] - v0->coords[0];
 | 
			
		||||
    yc = vc->coords[1] - v0->coords[1];
 | 
			
		||||
    zc = vc->coords[2] - v0->coords[2];
 | 
			
		||||
 | 
			
		||||
    /* Compute (vp - v0) cross (vc - v0) */
 | 
			
		||||
    n[0] = yp*zc - zp*yc;
 | 
			
		||||
    n[1] = zp*xc - xp*zc;
 | 
			
		||||
    n[2] = xp*yc - yp*xc;
 | 
			
		||||
 | 
			
		||||
    dot = n[0]*norm[0] + n[1]*norm[1] + n[2]*norm[2];
 | 
			
		||||
    if( ! check ) {
 | 
			
		||||
      /* Reverse the contribution of back-facing triangles to get
 | 
			
		||||
       * a reasonable normal for self-intersecting polygons (see above)
 | 
			
		||||
       */
 | 
			
		||||
      if( dot >= 0 ) {
 | 
			
		||||
	norm[0] += n[0]; norm[1] += n[1]; norm[2] += n[2];
 | 
			
		||||
      } else {
 | 
			
		||||
	norm[0] -= n[0]; norm[1] -= n[1]; norm[2] -= n[2];
 | 
			
		||||
      }
 | 
			
		||||
    } else if( dot != 0 ) {
 | 
			
		||||
      /* Check the new orientation for consistency with previous triangles */
 | 
			
		||||
      if( dot > 0 ) {
 | 
			
		||||
	if( sign < 0 ) return SIGN_INCONSISTENT;
 | 
			
		||||
	sign = 1;
 | 
			
		||||
      } else {
 | 
			
		||||
	if( sign > 0 ) return SIGN_INCONSISTENT;
 | 
			
		||||
	sign = -1;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return sign;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* __gl_renderCache( tess ) takes a single contour and tries to render it
 | 
			
		||||
 * as a triangle fan.  This handles convex polygons, as well as some
 | 
			
		||||
 * non-convex polygons if we get lucky.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns TRUE if the polygon was successfully rendered.  The rendering
 | 
			
		||||
 * output is provided as callbacks (see the api).
 | 
			
		||||
 */
 | 
			
		||||
GLboolean __gl_renderCache( GLUtesselator *tess )
 | 
			
		||||
{
 | 
			
		||||
  CachedVertex *v0 = tess->cache;
 | 
			
		||||
  CachedVertex *vn = v0 + tess->cacheCount;
 | 
			
		||||
  CachedVertex *vc;
 | 
			
		||||
  GLdouble norm[3];
 | 
			
		||||
  int sign;
 | 
			
		||||
 | 
			
		||||
  if( tess->cacheCount < 3 ) {
 | 
			
		||||
    /* Degenerate contour -- no output */
 | 
			
		||||
    return TRUE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  norm[0] = tess->normal[0];
 | 
			
		||||
  norm[1] = tess->normal[1];
 | 
			
		||||
  norm[2] = tess->normal[2];
 | 
			
		||||
  if( norm[0] == 0 && norm[1] == 0 && norm[2] == 0 ) {
 | 
			
		||||
    ComputeNormal( tess, norm, FALSE );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  sign = ComputeNormal( tess, norm, TRUE );
 | 
			
		||||
  if( sign == SIGN_INCONSISTENT ) {
 | 
			
		||||
    /* Fan triangles did not have a consistent orientation */
 | 
			
		||||
    return FALSE;
 | 
			
		||||
  }
 | 
			
		||||
  if( sign == 0 ) {
 | 
			
		||||
    /* All triangles were degenerate */
 | 
			
		||||
    return TRUE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Make sure we do the right thing for each winding rule */
 | 
			
		||||
  switch( tess->windingRule ) {
 | 
			
		||||
  case GLU_TESS_WINDING_ODD:
 | 
			
		||||
  case GLU_TESS_WINDING_NONZERO:
 | 
			
		||||
    break;
 | 
			
		||||
  case GLU_TESS_WINDING_POSITIVE:
 | 
			
		||||
    if( sign < 0 ) return TRUE;
 | 
			
		||||
    break;
 | 
			
		||||
  case GLU_TESS_WINDING_NEGATIVE:
 | 
			
		||||
    if( sign > 0 ) return TRUE;
 | 
			
		||||
    break;
 | 
			
		||||
  case GLU_TESS_WINDING_ABS_GEQ_TWO:
 | 
			
		||||
    return TRUE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  CALL_BEGIN_OR_BEGIN_DATA( tess->boundaryOnly ? GL_LINE_LOOP
 | 
			
		||||
			  : (tess->cacheCount > 3) ? GL_TRIANGLE_FAN
 | 
			
		||||
			  : GL_TRIANGLES );
 | 
			
		||||
 | 
			
		||||
  CALL_VERTEX_OR_VERTEX_DATA( v0->data ); 
 | 
			
		||||
  if( sign > 0 ) {
 | 
			
		||||
    for( vc = v0+1; vc < vn; ++vc ) {
 | 
			
		||||
      CALL_VERTEX_OR_VERTEX_DATA( vc->data ); 
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    for( vc = vn-1; vc > v0; --vc ) {
 | 
			
		||||
      CALL_VERTEX_OR_VERTEX_DATA( vc->data ); 
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  CALL_END_OR_END_DATA();
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,53 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
** Author: Eric Veach, July 1994.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __render_h_
 | 
			
		||||
#define __render_h_
 | 
			
		||||
 | 
			
		||||
#include "mesh.h"
 | 
			
		||||
#include "tesselator.h"
 | 
			
		||||
 | 
			
		||||
/* __gl_renderMesh( tess, mesh ) takes a mesh and breaks it into triangle
 | 
			
		||||
 * fans, strips, and separate triangles.  A substantial effort is made
 | 
			
		||||
 * to use as few rendering primitives as possible (ie. to make the fans
 | 
			
		||||
 * and strips as large as possible).
 | 
			
		||||
 *
 | 
			
		||||
 * The rendering output is provided as callbacks (see the api).
 | 
			
		||||
 */
 | 
			
		||||
void __gl_renderMesh( GLUtesselator *tess, GLUmesh *mesh );
 | 
			
		||||
void __gl_renderBoundary( GLUtesselator *tess, GLUmesh *mesh );
 | 
			
		||||
 | 
			
		||||
GLboolean __gl_renderCache( GLUtesselator *tess );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,78 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
** Author: Eric Veach, July 1994.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __sweep_h_
 | 
			
		||||
#define __sweep_h_
 | 
			
		||||
 | 
			
		||||
#include "mesh.h"
 | 
			
		||||
#include "tesselator.h"
 | 
			
		||||
 | 
			
		||||
/* __gl_computeInterior( tess ) computes the planar arrangement specified
 | 
			
		||||
 * by the given contours, and further subdivides this arrangement
 | 
			
		||||
 * into regions.  Each region is marked "inside" if it belongs
 | 
			
		||||
 * to the polygon, according to the rule given by tess->windingRule.
 | 
			
		||||
 * Each interior region is guaranteed be monotone.
 | 
			
		||||
 */
 | 
			
		||||
int __gl_computeInterior( GLUtesselator *tess );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* The following is here *only* for access by debugging routines */
 | 
			
		||||
 | 
			
		||||
#include "dict.h"
 | 
			
		||||
 | 
			
		||||
/* For each pair of adjacent edges crossing the sweep line, there is
 | 
			
		||||
 * an ActiveRegion to represent the region between them.  The active
 | 
			
		||||
 * regions are kept in sorted order in a dynamic dictionary.  As the
 | 
			
		||||
 * sweep line crosses each vertex, we update the affected regions.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
struct ActiveRegion {
 | 
			
		||||
  GLUhalfEdge	*eUp;		/* upper edge, directed right to left */
 | 
			
		||||
  DictNode	*nodeUp;	/* dictionary node corresponding to eUp */
 | 
			
		||||
  int		windingNumber;	/* used to determine which regions are
 | 
			
		||||
                                 * inside the polygon */
 | 
			
		||||
  GLboolean	inside;		/* is this region inside the polygon? */
 | 
			
		||||
  GLboolean	sentinel;	/* marks fake edges at t = +/-infinity */
 | 
			
		||||
  GLboolean	dirty;		/* marks regions where the upper or lower
 | 
			
		||||
                                 * edge has changed, but we haven't checked
 | 
			
		||||
                                 * whether they intersect yet */
 | 
			
		||||
  GLboolean	fixUpperEdge;	/* marks temporary edges introduced when
 | 
			
		||||
                                 * we process a "right vertex" (one without
 | 
			
		||||
                                 * any edges leaving to the right) */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define RegionBelow(r)	((ActiveRegion *) dictKey(dictPred((r)->nodeUp)))
 | 
			
		||||
#define RegionAbove(r)	((ActiveRegion *) dictKey(dictSucc((r)->nodeUp)))
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,632 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
** Author: Eric Veach, July 1994.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "gluos.h"
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <setjmp.h>
 | 
			
		||||
#include "memalloc.h"
 | 
			
		||||
#include "tess.h"
 | 
			
		||||
#include "mesh.h"
 | 
			
		||||
#include "normal.h"
 | 
			
		||||
#include "sweep.h"
 | 
			
		||||
#include "tessmono.h"
 | 
			
		||||
#include "render.h"
 | 
			
		||||
 | 
			
		||||
#define GLU_TESS_DEFAULT_TOLERANCE 0.0
 | 
			
		||||
#define GLU_TESS_MESH		100112	/* void (*)(GLUmesh *mesh)	    */
 | 
			
		||||
 | 
			
		||||
#ifndef TRUE
 | 
			
		||||
#define TRUE 1
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef FALSE
 | 
			
		||||
#define FALSE 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*ARGSUSED*/ static void GLAPIENTRY noBegin( GLenum type ) {}
 | 
			
		||||
/*ARGSUSED*/ static void GLAPIENTRY noEdgeFlag( GLboolean boundaryEdge ) {}
 | 
			
		||||
/*ARGSUSED*/ static void GLAPIENTRY noVertex( void *data ) {}
 | 
			
		||||
/*ARGSUSED*/ static void GLAPIENTRY noEnd( void ) {}
 | 
			
		||||
/*ARGSUSED*/ static void GLAPIENTRY noError( GLenum errnum ) {}
 | 
			
		||||
/*ARGSUSED*/ static void GLAPIENTRY noCombine( GLdouble coords[3], void *data[4],
 | 
			
		||||
				    GLfloat weight[4], void **dataOut ) {}
 | 
			
		||||
/*ARGSUSED*/ static void GLAPIENTRY noMesh( GLUmesh *mesh ) {}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*ARGSUSED*/ void GLAPIENTRY __gl_noBeginData( GLenum type,
 | 
			
		||||
					     void *polygonData ) {}
 | 
			
		||||
/*ARGSUSED*/ void GLAPIENTRY __gl_noEdgeFlagData( GLboolean boundaryEdge,
 | 
			
		||||
				       void *polygonData ) {}
 | 
			
		||||
/*ARGSUSED*/ void GLAPIENTRY __gl_noVertexData( void *data,
 | 
			
		||||
					      void *polygonData ) {}
 | 
			
		||||
/*ARGSUSED*/ void GLAPIENTRY __gl_noEndData( void *polygonData ) {}
 | 
			
		||||
/*ARGSUSED*/ void GLAPIENTRY __gl_noErrorData( GLenum errnum,
 | 
			
		||||
					     void *polygonData ) {}
 | 
			
		||||
/*ARGSUSED*/ void GLAPIENTRY __gl_noCombineData( GLdouble coords[3],
 | 
			
		||||
					       void *data[4],
 | 
			
		||||
					       GLfloat weight[4],
 | 
			
		||||
					       void **outData,
 | 
			
		||||
					       void *polygonData ) {}
 | 
			
		||||
 | 
			
		||||
/* Half-edges are allocated in pairs (see mesh.c) */
 | 
			
		||||
typedef struct { GLUhalfEdge e, eSym; } EdgePair;
 | 
			
		||||
 | 
			
		||||
#undef	MAX
 | 
			
		||||
#define MAX(a,b)	((a) > (b) ? (a) : (b))
 | 
			
		||||
#define MAX_FAST_ALLOC	(MAX(sizeof(EdgePair), \
 | 
			
		||||
                         MAX(sizeof(GLUvertex),sizeof(GLUface))))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLUtesselator * GLAPIENTRY
 | 
			
		||||
gluNewTess( void )
 | 
			
		||||
{
 | 
			
		||||
  GLUtesselator *tess;
 | 
			
		||||
 | 
			
		||||
  /* Only initialize fields which can be changed by the api.  Other fields
 | 
			
		||||
   * are initialized where they are used.
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  if (memInit( MAX_FAST_ALLOC ) == 0) {
 | 
			
		||||
     return 0;			/* out of memory */
 | 
			
		||||
  }
 | 
			
		||||
  tess = (GLUtesselator *)memAlloc( sizeof( GLUtesselator ));
 | 
			
		||||
  if (tess == NULL) {
 | 
			
		||||
     return 0;			/* out of memory */
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  tess->state = T_DORMANT;
 | 
			
		||||
 | 
			
		||||
  tess->normal[0] = 0;
 | 
			
		||||
  tess->normal[1] = 0;
 | 
			
		||||
  tess->normal[2] = 0;
 | 
			
		||||
 | 
			
		||||
  tess->relTolerance = GLU_TESS_DEFAULT_TOLERANCE;
 | 
			
		||||
  tess->windingRule = GLU_TESS_WINDING_ODD;
 | 
			
		||||
  tess->flagBoundary = FALSE;
 | 
			
		||||
  tess->boundaryOnly = FALSE;
 | 
			
		||||
 | 
			
		||||
  tess->callBegin = &noBegin;
 | 
			
		||||
  tess->callEdgeFlag = &noEdgeFlag;
 | 
			
		||||
  tess->callVertex = &noVertex;
 | 
			
		||||
  tess->callEnd = &noEnd;
 | 
			
		||||
 | 
			
		||||
  tess->callError = &noError;
 | 
			
		||||
  tess->callCombine = &noCombine;
 | 
			
		||||
  tess->callMesh = &noMesh;
 | 
			
		||||
 | 
			
		||||
  tess->callBeginData= &__gl_noBeginData;
 | 
			
		||||
  tess->callEdgeFlagData= &__gl_noEdgeFlagData;
 | 
			
		||||
  tess->callVertexData= &__gl_noVertexData;
 | 
			
		||||
  tess->callEndData= &__gl_noEndData;
 | 
			
		||||
  tess->callErrorData= &__gl_noErrorData;
 | 
			
		||||
  tess->callCombineData= &__gl_noCombineData;
 | 
			
		||||
 | 
			
		||||
  tess->polygonData= NULL;
 | 
			
		||||
 | 
			
		||||
  return tess;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void MakeDormant( GLUtesselator *tess )
 | 
			
		||||
{
 | 
			
		||||
  /* Return the tessellator to its original dormant state. */
 | 
			
		||||
 | 
			
		||||
  if( tess->mesh != NULL ) {
 | 
			
		||||
    __gl_meshDeleteMesh( tess->mesh );
 | 
			
		||||
  }
 | 
			
		||||
  tess->state = T_DORMANT;
 | 
			
		||||
  tess->lastEdge = NULL;
 | 
			
		||||
  tess->mesh = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define RequireState( tess, s )   if( tess->state != s ) GotoState(tess,s)
 | 
			
		||||
 | 
			
		||||
static void GotoState( GLUtesselator *tess, enum TessState newState )
 | 
			
		||||
{
 | 
			
		||||
  while( tess->state != newState ) {
 | 
			
		||||
    /* We change the current state one level at a time, to get to
 | 
			
		||||
     * the desired state.
 | 
			
		||||
     */
 | 
			
		||||
    if( tess->state < newState ) {
 | 
			
		||||
      switch( tess->state ) {
 | 
			
		||||
      case T_DORMANT:
 | 
			
		||||
	CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_BEGIN_POLYGON );
 | 
			
		||||
	gluTessBeginPolygon( tess, NULL );
 | 
			
		||||
	break;
 | 
			
		||||
      case T_IN_POLYGON:
 | 
			
		||||
	CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_BEGIN_CONTOUR );
 | 
			
		||||
	gluTessBeginContour( tess );
 | 
			
		||||
	break;
 | 
			
		||||
      default:
 | 
			
		||||
	 ;
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      switch( tess->state ) {
 | 
			
		||||
      case T_IN_CONTOUR:
 | 
			
		||||
	CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_END_CONTOUR );
 | 
			
		||||
	gluTessEndContour( tess );
 | 
			
		||||
	break;
 | 
			
		||||
      case T_IN_POLYGON:
 | 
			
		||||
	CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_END_POLYGON );
 | 
			
		||||
	/* gluTessEndPolygon( tess ) is too much work! */
 | 
			
		||||
	MakeDormant( tess );
 | 
			
		||||
	break;
 | 
			
		||||
      default:
 | 
			
		||||
	 ;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void GLAPIENTRY
 | 
			
		||||
gluDeleteTess( GLUtesselator *tess )
 | 
			
		||||
{
 | 
			
		||||
  RequireState( tess, T_DORMANT );
 | 
			
		||||
  memFree( tess );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void GLAPIENTRY
 | 
			
		||||
gluTessProperty( GLUtesselator *tess, GLenum which, GLdouble value )
 | 
			
		||||
{
 | 
			
		||||
  GLenum windingRule;
 | 
			
		||||
 | 
			
		||||
  switch( which ) {
 | 
			
		||||
  case GLU_TESS_TOLERANCE:
 | 
			
		||||
    if( value < 0.0 || value > 1.0 ) break;
 | 
			
		||||
    tess->relTolerance = value;
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  case GLU_TESS_WINDING_RULE:
 | 
			
		||||
    windingRule = (GLenum) value;
 | 
			
		||||
    if( windingRule != value ) break;	/* not an integer */
 | 
			
		||||
 | 
			
		||||
    switch( windingRule ) {
 | 
			
		||||
    case GLU_TESS_WINDING_ODD:
 | 
			
		||||
    case GLU_TESS_WINDING_NONZERO:
 | 
			
		||||
    case GLU_TESS_WINDING_POSITIVE:
 | 
			
		||||
    case GLU_TESS_WINDING_NEGATIVE:
 | 
			
		||||
    case GLU_TESS_WINDING_ABS_GEQ_TWO:
 | 
			
		||||
      tess->windingRule = windingRule;
 | 
			
		||||
      return;
 | 
			
		||||
    default:
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  case GLU_TESS_BOUNDARY_ONLY:
 | 
			
		||||
    tess->boundaryOnly = (value != 0);
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  default:
 | 
			
		||||
    CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_ENUM );
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_VALUE );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Returns tessellator property */
 | 
			
		||||
void GLAPIENTRY
 | 
			
		||||
gluGetTessProperty( GLUtesselator *tess, GLenum which, GLdouble *value )
 | 
			
		||||
{
 | 
			
		||||
   switch (which) {
 | 
			
		||||
   case GLU_TESS_TOLERANCE:
 | 
			
		||||
      /* tolerance should be in range [0..1] */
 | 
			
		||||
      assert(0.0 <= tess->relTolerance && tess->relTolerance <= 1.0);
 | 
			
		||||
      *value= tess->relTolerance;
 | 
			
		||||
      break;
 | 
			
		||||
   case GLU_TESS_WINDING_RULE:
 | 
			
		||||
      assert(tess->windingRule == GLU_TESS_WINDING_ODD ||
 | 
			
		||||
	     tess->windingRule == GLU_TESS_WINDING_NONZERO ||
 | 
			
		||||
	     tess->windingRule == GLU_TESS_WINDING_POSITIVE ||
 | 
			
		||||
	     tess->windingRule == GLU_TESS_WINDING_NEGATIVE ||
 | 
			
		||||
	     tess->windingRule == GLU_TESS_WINDING_ABS_GEQ_TWO);
 | 
			
		||||
      *value= tess->windingRule;
 | 
			
		||||
      break;
 | 
			
		||||
   case GLU_TESS_BOUNDARY_ONLY:
 | 
			
		||||
      assert(tess->boundaryOnly == TRUE || tess->boundaryOnly == FALSE);
 | 
			
		||||
      *value= tess->boundaryOnly;
 | 
			
		||||
      break;
 | 
			
		||||
   default:
 | 
			
		||||
      *value= 0.0;
 | 
			
		||||
      CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_ENUM );
 | 
			
		||||
      break;
 | 
			
		||||
   }
 | 
			
		||||
} /* gluGetTessProperty() */
 | 
			
		||||
 | 
			
		||||
void GLAPIENTRY
 | 
			
		||||
gluTessNormal( GLUtesselator *tess, GLdouble x, GLdouble y, GLdouble z )
 | 
			
		||||
{
 | 
			
		||||
  tess->normal[0] = x;
 | 
			
		||||
  tess->normal[1] = y;
 | 
			
		||||
  tess->normal[2] = z;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLAPIENTRY
 | 
			
		||||
gluTessCallback( GLUtesselator *tess, GLenum which, _GLUfuncptr fn)
 | 
			
		||||
{
 | 
			
		||||
  switch( which ) {
 | 
			
		||||
  case GLU_TESS_BEGIN:
 | 
			
		||||
    tess->callBegin = (fn == NULL) ? &noBegin : (void (GLAPIENTRY *)(GLenum)) fn;
 | 
			
		||||
    return;
 | 
			
		||||
  case GLU_TESS_BEGIN_DATA:
 | 
			
		||||
    tess->callBeginData = (fn == NULL) ?
 | 
			
		||||
	&__gl_noBeginData : (void (GLAPIENTRY *)(GLenum, void *)) fn;
 | 
			
		||||
    return;
 | 
			
		||||
  case GLU_TESS_EDGE_FLAG:
 | 
			
		||||
    tess->callEdgeFlag = (fn == NULL) ? &noEdgeFlag :
 | 
			
		||||
					(void (GLAPIENTRY *)(GLboolean)) fn;
 | 
			
		||||
    /* If the client wants boundary edges to be flagged,
 | 
			
		||||
     * we render everything as separate triangles (no strips or fans).
 | 
			
		||||
     */
 | 
			
		||||
    tess->flagBoundary = (fn != NULL);
 | 
			
		||||
    return;
 | 
			
		||||
  case GLU_TESS_EDGE_FLAG_DATA:
 | 
			
		||||
    tess->callEdgeFlagData= (fn == NULL) ?
 | 
			
		||||
	&__gl_noEdgeFlagData : (void (GLAPIENTRY *)(GLboolean, void *)) fn;
 | 
			
		||||
    /* If the client wants boundary edges to be flagged,
 | 
			
		||||
     * we render everything as separate triangles (no strips or fans).
 | 
			
		||||
     */
 | 
			
		||||
    tess->flagBoundary = (fn != NULL);
 | 
			
		||||
    return;
 | 
			
		||||
  case GLU_TESS_VERTEX:
 | 
			
		||||
    tess->callVertex = (fn == NULL) ? &noVertex :
 | 
			
		||||
				      (void (GLAPIENTRY *)(void *)) fn;
 | 
			
		||||
    return;
 | 
			
		||||
  case GLU_TESS_VERTEX_DATA:
 | 
			
		||||
    tess->callVertexData = (fn == NULL) ?
 | 
			
		||||
	&__gl_noVertexData : (void (GLAPIENTRY *)(void *, void *)) fn;
 | 
			
		||||
    return;
 | 
			
		||||
  case GLU_TESS_END:
 | 
			
		||||
    tess->callEnd = (fn == NULL) ? &noEnd : (void (GLAPIENTRY *)(void)) fn;
 | 
			
		||||
    return;
 | 
			
		||||
  case GLU_TESS_END_DATA:
 | 
			
		||||
    tess->callEndData = (fn == NULL) ? &__gl_noEndData :
 | 
			
		||||
				       (void (GLAPIENTRY *)(void *)) fn;
 | 
			
		||||
    return;
 | 
			
		||||
  case GLU_TESS_ERROR:
 | 
			
		||||
    tess->callError = (fn == NULL) ? &noError : (void (GLAPIENTRY *)(GLenum)) fn;
 | 
			
		||||
    return;
 | 
			
		||||
  case GLU_TESS_ERROR_DATA:
 | 
			
		||||
    tess->callErrorData = (fn == NULL) ?
 | 
			
		||||
	&__gl_noErrorData : (void (GLAPIENTRY *)(GLenum, void *)) fn;
 | 
			
		||||
    return;
 | 
			
		||||
  case GLU_TESS_COMBINE:
 | 
			
		||||
    tess->callCombine = (fn == NULL) ? &noCombine :
 | 
			
		||||
	(void (GLAPIENTRY *)(GLdouble [3],void *[4], GLfloat [4], void ** )) fn;
 | 
			
		||||
    return;
 | 
			
		||||
  case GLU_TESS_COMBINE_DATA:
 | 
			
		||||
    tess->callCombineData = (fn == NULL) ? &__gl_noCombineData :
 | 
			
		||||
					   (void (GLAPIENTRY *)(GLdouble [3],
 | 
			
		||||
						     void *[4],
 | 
			
		||||
						     GLfloat [4],
 | 
			
		||||
						     void **,
 | 
			
		||||
						     void *)) fn;
 | 
			
		||||
    return;
 | 
			
		||||
  case GLU_TESS_MESH:
 | 
			
		||||
    tess->callMesh = (fn == NULL) ? &noMesh : (void (GLAPIENTRY *)(GLUmesh *)) fn;
 | 
			
		||||
    return;
 | 
			
		||||
  default:
 | 
			
		||||
    CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_ENUM );
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int AddVertex( GLUtesselator *tess, GLdouble coords[3], void *data )
 | 
			
		||||
{
 | 
			
		||||
  GLUhalfEdge *e;
 | 
			
		||||
 | 
			
		||||
  e = tess->lastEdge;
 | 
			
		||||
  if( e == NULL ) {
 | 
			
		||||
    /* Make a self-loop (one vertex, one edge). */
 | 
			
		||||
 | 
			
		||||
    e = __gl_meshMakeEdge( tess->mesh );
 | 
			
		||||
    if (e == NULL) return 0;
 | 
			
		||||
    if ( !__gl_meshSplice( e, e->Sym ) ) return 0;
 | 
			
		||||
  } else {
 | 
			
		||||
    /* Create a new vertex and edge which immediately follow e
 | 
			
		||||
     * in the ordering around the left face.
 | 
			
		||||
     */
 | 
			
		||||
    if (__gl_meshSplitEdge( e ) == NULL) return 0;
 | 
			
		||||
    e = e->Lnext;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* The new vertex is now e->Org. */
 | 
			
		||||
  e->Org->data = data;
 | 
			
		||||
  e->Org->coords[0] = coords[0];
 | 
			
		||||
  e->Org->coords[1] = coords[1];
 | 
			
		||||
  e->Org->coords[2] = coords[2];
 | 
			
		||||
 | 
			
		||||
  /* The winding of an edge says how the winding number changes as we
 | 
			
		||||
   * cross from the edge''s right face to its left face.  We add the
 | 
			
		||||
   * vertices in such an order that a CCW contour will add +1 to
 | 
			
		||||
   * the winding number of the region inside the contour.
 | 
			
		||||
   */
 | 
			
		||||
  e->winding = 1;
 | 
			
		||||
  e->Sym->winding = -1;
 | 
			
		||||
 | 
			
		||||
  tess->lastEdge = e;
 | 
			
		||||
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void CacheVertex( GLUtesselator *tess, GLdouble coords[3], void *data )
 | 
			
		||||
{
 | 
			
		||||
  CachedVertex *v = &tess->cache[tess->cacheCount];
 | 
			
		||||
 | 
			
		||||
  v->data = data;
 | 
			
		||||
  v->coords[0] = coords[0];
 | 
			
		||||
  v->coords[1] = coords[1];
 | 
			
		||||
  v->coords[2] = coords[2];
 | 
			
		||||
  ++tess->cacheCount;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int EmptyCache( GLUtesselator *tess )
 | 
			
		||||
{
 | 
			
		||||
  CachedVertex *v = tess->cache;
 | 
			
		||||
  CachedVertex *vLast;
 | 
			
		||||
 | 
			
		||||
  tess->mesh = __gl_meshNewMesh();
 | 
			
		||||
  if (tess->mesh == NULL) return 0;
 | 
			
		||||
 | 
			
		||||
  for( vLast = v + tess->cacheCount; v < vLast; ++v ) {
 | 
			
		||||
    if ( !AddVertex( tess, v->coords, v->data ) ) return 0;
 | 
			
		||||
  }
 | 
			
		||||
  tess->cacheCount = 0;
 | 
			
		||||
  tess->emptyCache = FALSE;
 | 
			
		||||
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void GLAPIENTRY
 | 
			
		||||
gluTessVertex( GLUtesselator *tess, GLdouble coords[3], void *data )
 | 
			
		||||
{
 | 
			
		||||
  int i, tooLarge = FALSE;
 | 
			
		||||
  GLdouble x, clamped[3];
 | 
			
		||||
 | 
			
		||||
  RequireState( tess, T_IN_CONTOUR );
 | 
			
		||||
 | 
			
		||||
  if( tess->emptyCache ) {
 | 
			
		||||
    if ( !EmptyCache( tess ) ) {
 | 
			
		||||
       CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY );
 | 
			
		||||
       return;
 | 
			
		||||
    }
 | 
			
		||||
    tess->lastEdge = NULL;
 | 
			
		||||
  }
 | 
			
		||||
  for( i = 0; i < 3; ++i ) {
 | 
			
		||||
    x = coords[i];
 | 
			
		||||
    if( x < - GLU_TESS_MAX_COORD ) {
 | 
			
		||||
      x = - GLU_TESS_MAX_COORD;
 | 
			
		||||
      tooLarge = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
    if( x > GLU_TESS_MAX_COORD ) {
 | 
			
		||||
      x = GLU_TESS_MAX_COORD;
 | 
			
		||||
      tooLarge = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
    clamped[i] = x;
 | 
			
		||||
  }
 | 
			
		||||
  if( tooLarge ) {
 | 
			
		||||
    CALL_ERROR_OR_ERROR_DATA( GLU_TESS_COORD_TOO_LARGE );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if( tess->mesh == NULL ) {
 | 
			
		||||
    if( tess->cacheCount < TESS_MAX_CACHE ) {
 | 
			
		||||
      CacheVertex( tess, clamped, data );
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    if ( !EmptyCache( tess ) ) {
 | 
			
		||||
       CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY );
 | 
			
		||||
       return;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if ( !AddVertex( tess, clamped, data ) ) {
 | 
			
		||||
       CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void GLAPIENTRY
 | 
			
		||||
gluTessBeginPolygon( GLUtesselator *tess, void *data )
 | 
			
		||||
{
 | 
			
		||||
  RequireState( tess, T_DORMANT );
 | 
			
		||||
 | 
			
		||||
  tess->state = T_IN_POLYGON;
 | 
			
		||||
  tess->cacheCount = 0;
 | 
			
		||||
  tess->emptyCache = FALSE;
 | 
			
		||||
  tess->mesh = NULL;
 | 
			
		||||
 | 
			
		||||
  tess->polygonData= data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void GLAPIENTRY
 | 
			
		||||
gluTessBeginContour( GLUtesselator *tess )
 | 
			
		||||
{
 | 
			
		||||
  RequireState( tess, T_IN_POLYGON );
 | 
			
		||||
 | 
			
		||||
  tess->state = T_IN_CONTOUR;
 | 
			
		||||
  tess->lastEdge = NULL;
 | 
			
		||||
  if( tess->cacheCount > 0 ) {
 | 
			
		||||
    /* Just set a flag so we don't get confused by empty contours
 | 
			
		||||
     * -- these can be generated accidentally with the obsolete
 | 
			
		||||
     * NextContour() interface.
 | 
			
		||||
     */
 | 
			
		||||
    tess->emptyCache = TRUE;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void GLAPIENTRY
 | 
			
		||||
gluTessEndContour( GLUtesselator *tess )
 | 
			
		||||
{
 | 
			
		||||
  RequireState( tess, T_IN_CONTOUR );
 | 
			
		||||
  tess->state = T_IN_POLYGON;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLAPIENTRY
 | 
			
		||||
gluTessEndPolygon( GLUtesselator *tess )
 | 
			
		||||
{
 | 
			
		||||
  GLUmesh *mesh;
 | 
			
		||||
 | 
			
		||||
  if (setjmp(tess->env) != 0) { 
 | 
			
		||||
     /* come back here if out of memory */
 | 
			
		||||
     CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY );
 | 
			
		||||
     return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  RequireState( tess, T_IN_POLYGON );
 | 
			
		||||
  tess->state = T_DORMANT;
 | 
			
		||||
 | 
			
		||||
  if( tess->mesh == NULL ) {
 | 
			
		||||
    if( ! tess->flagBoundary && tess->callMesh == &noMesh ) {
 | 
			
		||||
 | 
			
		||||
      /* Try some special code to make the easy cases go quickly
 | 
			
		||||
       * (eg. convex polygons).  This code does NOT handle multiple contours,
 | 
			
		||||
       * intersections, edge flags, and of course it does not generate
 | 
			
		||||
       * an explicit mesh either.
 | 
			
		||||
       */
 | 
			
		||||
      if( __gl_renderCache( tess )) {
 | 
			
		||||
	tess->polygonData= NULL;
 | 
			
		||||
	return;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if ( !EmptyCache( tess ) ) longjmp(tess->env,1); /* could've used a label*/
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Determine the polygon normal and project vertices onto the plane
 | 
			
		||||
   * of the polygon.
 | 
			
		||||
   */
 | 
			
		||||
  __gl_projectPolygon( tess );
 | 
			
		||||
 | 
			
		||||
  /* __gl_computeInterior( tess ) computes the planar arrangement specified
 | 
			
		||||
   * by the given contours, and further subdivides this arrangement
 | 
			
		||||
   * into regions.  Each region is marked "inside" if it belongs
 | 
			
		||||
   * to the polygon, according to the rule given by tess->windingRule.
 | 
			
		||||
   * Each interior region is guaranteed be monotone.
 | 
			
		||||
   */
 | 
			
		||||
  if ( !__gl_computeInterior( tess ) ) {
 | 
			
		||||
     longjmp(tess->env,1);	/* could've used a label */
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  mesh = tess->mesh;
 | 
			
		||||
  if( ! tess->fatalError ) {
 | 
			
		||||
    int rc = 1;
 | 
			
		||||
 | 
			
		||||
    /* If the user wants only the boundary contours, we throw away all edges
 | 
			
		||||
     * except those which separate the interior from the exterior.
 | 
			
		||||
     * Otherwise we tessellate all the regions marked "inside".
 | 
			
		||||
     */
 | 
			
		||||
    if( tess->boundaryOnly ) {
 | 
			
		||||
      rc = __gl_meshSetWindingNumber( mesh, 1, TRUE );
 | 
			
		||||
    } else {
 | 
			
		||||
      rc = __gl_meshTessellateInterior( mesh );
 | 
			
		||||
    }
 | 
			
		||||
    if (rc == 0) longjmp(tess->env,1);	/* could've used a label */
 | 
			
		||||
 | 
			
		||||
    __gl_meshCheckMesh( mesh );
 | 
			
		||||
 | 
			
		||||
    if( tess->callBegin != &noBegin || tess->callEnd != &noEnd
 | 
			
		||||
       || tess->callVertex != &noVertex || tess->callEdgeFlag != &noEdgeFlag
 | 
			
		||||
       || tess->callBeginData != &__gl_noBeginData
 | 
			
		||||
       || tess->callEndData != &__gl_noEndData
 | 
			
		||||
       || tess->callVertexData != &__gl_noVertexData
 | 
			
		||||
       || tess->callEdgeFlagData != &__gl_noEdgeFlagData )
 | 
			
		||||
    {
 | 
			
		||||
      if( tess->boundaryOnly ) {
 | 
			
		||||
	__gl_renderBoundary( tess, mesh );  /* output boundary contours */
 | 
			
		||||
      } else {
 | 
			
		||||
	__gl_renderMesh( tess, mesh );	   /* output strips and fans */
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if( tess->callMesh != &noMesh ) {
 | 
			
		||||
 | 
			
		||||
      /* Throw away the exterior faces, so that all faces are interior.
 | 
			
		||||
       * This way the user doesn't have to check the "inside" flag,
 | 
			
		||||
       * and we don't need to even reveal its existence.  It also leaves
 | 
			
		||||
       * the freedom for an implementation to not generate the exterior
 | 
			
		||||
       * faces in the first place.
 | 
			
		||||
       */
 | 
			
		||||
      __gl_meshDiscardExterior( mesh );
 | 
			
		||||
      (*tess->callMesh)( mesh );		/* user wants the mesh itself */
 | 
			
		||||
      tess->mesh = NULL;
 | 
			
		||||
      tess->polygonData= NULL;
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  __gl_meshDeleteMesh( mesh );
 | 
			
		||||
  tess->polygonData= NULL;
 | 
			
		||||
  tess->mesh = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*XXXblythe unused function*/
 | 
			
		||||
#if 0
 | 
			
		||||
void GLAPIENTRY
 | 
			
		||||
gluDeleteMesh( GLUmesh *mesh )
 | 
			
		||||
{
 | 
			
		||||
  __gl_meshDeleteMesh( mesh );
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*******************************************************/
 | 
			
		||||
 | 
			
		||||
/* Obsolete calls -- for backward compatibility */
 | 
			
		||||
 | 
			
		||||
void GLAPIENTRY
 | 
			
		||||
gluBeginPolygon( GLUtesselator *tess )
 | 
			
		||||
{
 | 
			
		||||
  gluTessBeginPolygon( tess, NULL );
 | 
			
		||||
  gluTessBeginContour( tess );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*ARGSUSED*/
 | 
			
		||||
void GLAPIENTRY
 | 
			
		||||
gluNextContour( GLUtesselator *tess, GLenum type )
 | 
			
		||||
{
 | 
			
		||||
  gluTessEndContour( tess );
 | 
			
		||||
  gluTessBeginContour( tess );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void GLAPIENTRY
 | 
			
		||||
gluEndPolygon( GLUtesselator *tess )
 | 
			
		||||
{
 | 
			
		||||
  gluTessEndContour( tess );
 | 
			
		||||
  gluTessEndPolygon( tess );
 | 
			
		||||
}
 | 
			
		||||
@@ -1,164 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
** Author: Eric Veach, July 1994.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __tess_h_
 | 
			
		||||
#define __tess_h_
 | 
			
		||||
 | 
			
		||||
#include <setjmp.h>
 | 
			
		||||
#include "mesh.h"
 | 
			
		||||
#include "dict.h"
 | 
			
		||||
#include "priorityq.h"
 | 
			
		||||
 | 
			
		||||
/* The begin/end calls must be properly nested.  We keep track of
 | 
			
		||||
 * the current state to enforce the ordering.
 | 
			
		||||
 */
 | 
			
		||||
enum TessState { T_DORMANT, T_IN_POLYGON, T_IN_CONTOUR };
 | 
			
		||||
 | 
			
		||||
/* We cache vertex data for single-contour polygons so that we can
 | 
			
		||||
 * try a quick-and-dirty decomposition first.
 | 
			
		||||
 */
 | 
			
		||||
#define TESS_MAX_CACHE	100
 | 
			
		||||
 | 
			
		||||
typedef struct CachedVertex {
 | 
			
		||||
  GLdouble	coords[3];
 | 
			
		||||
  void		*data;
 | 
			
		||||
} CachedVertex;
 | 
			
		||||
 | 
			
		||||
struct GLUtesselator {
 | 
			
		||||
 | 
			
		||||
  /*** state needed for collecting the input data ***/
 | 
			
		||||
 | 
			
		||||
  enum TessState state;		/* what begin/end calls have we seen? */
 | 
			
		||||
 | 
			
		||||
  GLUhalfEdge	*lastEdge;	/* lastEdge->Org is the most recent vertex */
 | 
			
		||||
  GLUmesh	*mesh;		/* stores the input contours, and eventually
 | 
			
		||||
                                   the tessellation itself */
 | 
			
		||||
 | 
			
		||||
  void		(GLAPIENTRY *callError)( GLenum errnum );
 | 
			
		||||
 | 
			
		||||
  /*** state needed for projecting onto the sweep plane ***/
 | 
			
		||||
 | 
			
		||||
  GLdouble	normal[3];	/* user-specified normal (if provided) */
 | 
			
		||||
  GLdouble	sUnit[3];	/* unit vector in s-direction (debugging) */
 | 
			
		||||
  GLdouble	tUnit[3];	/* unit vector in t-direction (debugging) */
 | 
			
		||||
 | 
			
		||||
  /*** state needed for the line sweep ***/
 | 
			
		||||
 | 
			
		||||
  GLdouble	relTolerance;	/* tolerance for merging features */
 | 
			
		||||
  GLenum	windingRule;	/* rule for determining polygon interior */
 | 
			
		||||
  GLboolean	fatalError;	/* fatal error: needed combine callback */
 | 
			
		||||
 | 
			
		||||
  Dict		*dict;		/* edge dictionary for sweep line */
 | 
			
		||||
  PriorityQ	*pq;		/* priority queue of vertex events */
 | 
			
		||||
  GLUvertex	*event;		/* current sweep event being processed */
 | 
			
		||||
 | 
			
		||||
  void		(GLAPIENTRY *callCombine)( GLdouble coords[3], void *data[4],
 | 
			
		||||
			        GLfloat weight[4], void **outData );
 | 
			
		||||
 | 
			
		||||
  /*** state needed for rendering callbacks (see render.c) ***/
 | 
			
		||||
 | 
			
		||||
  GLboolean	flagBoundary;	/* mark boundary edges (use EdgeFlag) */
 | 
			
		||||
  GLboolean	boundaryOnly;	/* Extract contours, not triangles */
 | 
			
		||||
  GLUface	*lonelyTriList;
 | 
			
		||||
    /* list of triangles which could not be rendered as strips or fans */
 | 
			
		||||
 | 
			
		||||
  void		(GLAPIENTRY *callBegin)( GLenum type );
 | 
			
		||||
  void		(GLAPIENTRY *callEdgeFlag)( GLboolean boundaryEdge );
 | 
			
		||||
  void		(GLAPIENTRY *callVertex)( void *data );
 | 
			
		||||
  void		(GLAPIENTRY *callEnd)( void );
 | 
			
		||||
  void		(GLAPIENTRY *callMesh)( GLUmesh *mesh );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /*** state needed to cache single-contour polygons for renderCache() */
 | 
			
		||||
 | 
			
		||||
  GLboolean	emptyCache;		/* empty cache on next vertex() call */
 | 
			
		||||
  int		cacheCount;		/* number of cached vertices */
 | 
			
		||||
  CachedVertex	cache[TESS_MAX_CACHE];	/* the vertex data */
 | 
			
		||||
 | 
			
		||||
  /*** rendering callbacks that also pass polygon data  ***/ 
 | 
			
		||||
  void		(GLAPIENTRY *callBeginData)( GLenum type, void *polygonData );
 | 
			
		||||
  void		(GLAPIENTRY *callEdgeFlagData)( GLboolean boundaryEdge, 
 | 
			
		||||
				     void *polygonData );
 | 
			
		||||
  void		(GLAPIENTRY *callVertexData)( void *data, void *polygonData );
 | 
			
		||||
  void		(GLAPIENTRY *callEndData)( void *polygonData );
 | 
			
		||||
  void		(GLAPIENTRY *callErrorData)( GLenum errnum, void *polygonData );
 | 
			
		||||
  void		(GLAPIENTRY *callCombineData)( GLdouble coords[3], void *data[4],
 | 
			
		||||
				    GLfloat weight[4], void **outData,
 | 
			
		||||
				    void *polygonData );
 | 
			
		||||
 | 
			
		||||
  jmp_buf env;			/* place to jump to when memAllocs fail */
 | 
			
		||||
 | 
			
		||||
  void *polygonData;		/* client data for current polygon */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void GLAPIENTRY __gl_noBeginData( GLenum type, void *polygonData );
 | 
			
		||||
void GLAPIENTRY __gl_noEdgeFlagData( GLboolean boundaryEdge, void *polygonData );
 | 
			
		||||
void GLAPIENTRY __gl_noVertexData( void *data, void *polygonData );
 | 
			
		||||
void GLAPIENTRY __gl_noEndData( void *polygonData );
 | 
			
		||||
void GLAPIENTRY __gl_noErrorData( GLenum errnum, void *polygonData );
 | 
			
		||||
void GLAPIENTRY __gl_noCombineData( GLdouble coords[3], void *data[4],
 | 
			
		||||
			 GLfloat weight[4], void **outData,
 | 
			
		||||
			 void *polygonData );
 | 
			
		||||
 | 
			
		||||
#define CALL_BEGIN_OR_BEGIN_DATA(a) \
 | 
			
		||||
   if (tess->callBeginData != &__gl_noBeginData) \
 | 
			
		||||
      (*tess->callBeginData)((a),tess->polygonData); \
 | 
			
		||||
   else (*tess->callBegin)((a));
 | 
			
		||||
 | 
			
		||||
#define CALL_VERTEX_OR_VERTEX_DATA(a) \
 | 
			
		||||
   if (tess->callVertexData != &__gl_noVertexData) \
 | 
			
		||||
      (*tess->callVertexData)((a),tess->polygonData); \
 | 
			
		||||
   else (*tess->callVertex)((a));
 | 
			
		||||
 | 
			
		||||
#define CALL_EDGE_FLAG_OR_EDGE_FLAG_DATA(a) \
 | 
			
		||||
   if (tess->callEdgeFlagData != &__gl_noEdgeFlagData) \
 | 
			
		||||
      (*tess->callEdgeFlagData)((a),tess->polygonData); \
 | 
			
		||||
   else (*tess->callEdgeFlag)((a));
 | 
			
		||||
 | 
			
		||||
#define CALL_END_OR_END_DATA() \
 | 
			
		||||
   if (tess->callEndData != &__gl_noEndData) \
 | 
			
		||||
      (*tess->callEndData)(tess->polygonData); \
 | 
			
		||||
   else (*tess->callEnd)();
 | 
			
		||||
 | 
			
		||||
#define CALL_COMBINE_OR_COMBINE_DATA(a,b,c,d) \
 | 
			
		||||
   if (tess->callCombineData != &__gl_noCombineData) \
 | 
			
		||||
      (*tess->callCombineData)((a),(b),(c),(d),tess->polygonData); \
 | 
			
		||||
   else (*tess->callCombine)((a),(b),(c),(d));
 | 
			
		||||
 | 
			
		||||
#define CALL_ERROR_OR_ERROR_DATA(a) \
 | 
			
		||||
   if (tess->callErrorData != &__gl_noErrorData) \
 | 
			
		||||
      (*tess->callErrorData)((a),tess->polygonData); \
 | 
			
		||||
   else (*tess->callError)((a));
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,122 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 * Copyright (C) 2010 Intel Corporation
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __TESSELATOR_H__
 | 
			
		||||
#define __TESSELATOR_H__
 | 
			
		||||
 | 
			
		||||
/* This just includes the defines needed by the tesselator code */
 | 
			
		||||
 | 
			
		||||
#include "cogl/cogl-defines.h"
 | 
			
		||||
#include "cogl/cogl-gl-header.h"
 | 
			
		||||
 | 
			
		||||
typedef struct GLUtesselator GLUtesselator;
 | 
			
		||||
 | 
			
		||||
#define GLU_TESS_MAX_COORD 1.0e150
 | 
			
		||||
 | 
			
		||||
void gluBeginPolygon (GLUtesselator* tess);
 | 
			
		||||
void gluDeleteTess (GLUtesselator* tess);
 | 
			
		||||
void gluEndPolygon (GLUtesselator* tess);
 | 
			
		||||
 | 
			
		||||
typedef void (_GLUfuncptr)(void);
 | 
			
		||||
 | 
			
		||||
void gluGetTessProperty (GLUtesselator* tess, GLenum which, double* data);
 | 
			
		||||
 | 
			
		||||
GLUtesselator *gluNewTess (void);
 | 
			
		||||
void gluNextContour (GLUtesselator* tess, GLenum type);
 | 
			
		||||
 | 
			
		||||
void gluTessBeginContour (GLUtesselator* tess);
 | 
			
		||||
void gluTessBeginPolygon (GLUtesselator* tess, GLvoid* data);
 | 
			
		||||
void gluTessCallback (GLUtesselator* tess, GLenum which, _GLUfuncptr CallBackFunc);
 | 
			
		||||
void gluTessEndContour (GLUtesselator* tess);
 | 
			
		||||
void gluTessEndPolygon (GLUtesselator* tess);
 | 
			
		||||
void gluTessNormal (GLUtesselator* tess, double valueX, double valueY, double valueZ);
 | 
			
		||||
void gluTessProperty (GLUtesselator* tess, GLenum which, double data);
 | 
			
		||||
void gluTessVertex (GLUtesselator* tess, double *location, GLvoid* data);
 | 
			
		||||
 | 
			
		||||
/* ErrorCode */
 | 
			
		||||
#define GLU_INVALID_ENUM                   100900
 | 
			
		||||
#define GLU_INVALID_VALUE                  100901
 | 
			
		||||
#define GLU_OUT_OF_MEMORY                  100902
 | 
			
		||||
 | 
			
		||||
/* TessCallback */
 | 
			
		||||
#define GLU_TESS_BEGIN                     100100
 | 
			
		||||
#define GLU_BEGIN                          100100
 | 
			
		||||
#define GLU_TESS_VERTEX                    100101
 | 
			
		||||
#define GLU_VERTEX                         100101
 | 
			
		||||
#define GLU_TESS_END                       100102
 | 
			
		||||
#define GLU_END                            100102
 | 
			
		||||
#define GLU_TESS_ERROR                     100103
 | 
			
		||||
#define GLU_TESS_EDGE_FLAG                 100104
 | 
			
		||||
#define GLU_EDGE_FLAG                      100104
 | 
			
		||||
#define GLU_TESS_COMBINE                   100105
 | 
			
		||||
#define GLU_TESS_BEGIN_DATA                100106
 | 
			
		||||
#define GLU_TESS_VERTEX_DATA               100107
 | 
			
		||||
#define GLU_TESS_END_DATA                  100108
 | 
			
		||||
#define GLU_TESS_ERROR_DATA                100109
 | 
			
		||||
#define GLU_TESS_EDGE_FLAG_DATA            100110
 | 
			
		||||
#define GLU_TESS_COMBINE_DATA              100111
 | 
			
		||||
 | 
			
		||||
/* TessContour */
 | 
			
		||||
#define GLU_CW                             100120
 | 
			
		||||
#define GLU_CCW                            100121
 | 
			
		||||
#define GLU_INTERIOR                       100122
 | 
			
		||||
#define GLU_EXTERIOR                       100123
 | 
			
		||||
#define GLU_UNKNOWN                        100124
 | 
			
		||||
 | 
			
		||||
/* TessProperty */
 | 
			
		||||
#define GLU_TESS_WINDING_RULE              100140
 | 
			
		||||
#define GLU_TESS_BOUNDARY_ONLY             100141
 | 
			
		||||
#define GLU_TESS_TOLERANCE                 100142
 | 
			
		||||
 | 
			
		||||
/* TessError */
 | 
			
		||||
#define GLU_TESS_ERROR1                    100151
 | 
			
		||||
#define GLU_TESS_ERROR2                    100152
 | 
			
		||||
#define GLU_TESS_ERROR3                    100153
 | 
			
		||||
#define GLU_TESS_ERROR4                    100154
 | 
			
		||||
#define GLU_TESS_ERROR5                    100155
 | 
			
		||||
#define GLU_TESS_ERROR6                    100156
 | 
			
		||||
#define GLU_TESS_ERROR7                    100157
 | 
			
		||||
#define GLU_TESS_ERROR8                    100158
 | 
			
		||||
#define GLU_TESS_MISSING_BEGIN_POLYGON     100151
 | 
			
		||||
#define GLU_TESS_MISSING_BEGIN_CONTOUR     100152
 | 
			
		||||
#define GLU_TESS_MISSING_END_POLYGON       100153
 | 
			
		||||
#define GLU_TESS_MISSING_END_CONTOUR       100154
 | 
			
		||||
#define GLU_TESS_COORD_TOO_LARGE           100155
 | 
			
		||||
#define GLU_TESS_NEED_COMBINE_CALLBACK     100156
 | 
			
		||||
 | 
			
		||||
/* TessWinding */
 | 
			
		||||
#define GLU_TESS_WINDING_ODD               100130
 | 
			
		||||
#define GLU_TESS_WINDING_NONZERO           100131
 | 
			
		||||
#define GLU_TESS_WINDING_POSITIVE          100132
 | 
			
		||||
#define GLU_TESS_WINDING_NEGATIVE          100133
 | 
			
		||||
#define GLU_TESS_WINDING_ABS_GEQ_TWO       100134
 | 
			
		||||
 | 
			
		||||
#endif /* __TESSELATOR_H__ */
 | 
			
		||||
@@ -1,201 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
** Author: Eric Veach, July 1994.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "gluos.h"
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include "geom.h"
 | 
			
		||||
#include "mesh.h"
 | 
			
		||||
#include "tessmono.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#define AddWinding(eDst,eSrc)	(eDst->winding += eSrc->winding, \
 | 
			
		||||
				 eDst->Sym->winding += eSrc->Sym->winding)
 | 
			
		||||
 | 
			
		||||
/* __gl_meshTessellateMonoRegion( face ) tessellates a monotone region
 | 
			
		||||
 * (what else would it do??)  The region must consist of a single
 | 
			
		||||
 * loop of half-edges (see mesh.h) oriented CCW.  "Monotone" in this
 | 
			
		||||
 * case means that any vertical line intersects the interior of the
 | 
			
		||||
 * region in a single interval.  
 | 
			
		||||
 *
 | 
			
		||||
 * Tessellation consists of adding interior edges (actually pairs of
 | 
			
		||||
 * half-edges), to split the region into non-overlapping triangles.
 | 
			
		||||
 *
 | 
			
		||||
 * The basic idea is explained in Preparata and Shamos (which I don''t
 | 
			
		||||
 * have handy right now), although their implementation is more
 | 
			
		||||
 * complicated than this one.  The are two edge chains, an upper chain
 | 
			
		||||
 * and a lower chain.  We process all vertices from both chains in order,
 | 
			
		||||
 * from right to left.
 | 
			
		||||
 *
 | 
			
		||||
 * The algorithm ensures that the following invariant holds after each
 | 
			
		||||
 * vertex is processed: the untessellated region consists of two
 | 
			
		||||
 * chains, where one chain (say the upper) is a single edge, and
 | 
			
		||||
 * the other chain is concave.  The left vertex of the single edge
 | 
			
		||||
 * is always to the left of all vertices in the concave chain.
 | 
			
		||||
 *
 | 
			
		||||
 * Each step consists of adding the rightmost unprocessed vertex to one
 | 
			
		||||
 * of the two chains, and forming a fan of triangles from the rightmost
 | 
			
		||||
 * of two chain endpoints.  Determining whether we can add each triangle
 | 
			
		||||
 * to the fan is a simple orientation test.  By making the fan as large
 | 
			
		||||
 * as possible, we restore the invariant (check it yourself).
 | 
			
		||||
 */
 | 
			
		||||
int __gl_meshTessellateMonoRegion( GLUface *face )
 | 
			
		||||
{
 | 
			
		||||
  GLUhalfEdge *up, *lo;
 | 
			
		||||
 | 
			
		||||
  /* All edges are oriented CCW around the boundary of the region.
 | 
			
		||||
   * First, find the half-edge whose origin vertex is rightmost.
 | 
			
		||||
   * Since the sweep goes from left to right, face->anEdge should
 | 
			
		||||
   * be close to the edge we want.
 | 
			
		||||
   */
 | 
			
		||||
  up = face->anEdge;
 | 
			
		||||
  assert( up->Lnext != up && up->Lnext->Lnext != up );
 | 
			
		||||
 | 
			
		||||
  for( ; VertLeq( up->Dst, up->Org ); up = up->Lprev )
 | 
			
		||||
    ;
 | 
			
		||||
  for( ; VertLeq( up->Org, up->Dst ); up = up->Lnext )
 | 
			
		||||
    ;
 | 
			
		||||
  lo = up->Lprev;
 | 
			
		||||
 | 
			
		||||
  while( up->Lnext != lo ) {
 | 
			
		||||
    if( VertLeq( up->Dst, lo->Org )) {
 | 
			
		||||
      /* up->Dst is on the left.  It is safe to form triangles from lo->Org.
 | 
			
		||||
       * The EdgeGoesLeft test guarantees progress even when some triangles
 | 
			
		||||
       * are CW, given that the upper and lower chains are truly monotone.
 | 
			
		||||
       */
 | 
			
		||||
      while( lo->Lnext != up && (EdgeGoesLeft( lo->Lnext )
 | 
			
		||||
	     || EdgeSign( lo->Org, lo->Dst, lo->Lnext->Dst ) <= 0 )) {
 | 
			
		||||
	GLUhalfEdge *tempHalfEdge= __gl_meshConnect( lo->Lnext, lo );
 | 
			
		||||
	if (tempHalfEdge == NULL) return 0;
 | 
			
		||||
	lo = tempHalfEdge->Sym;
 | 
			
		||||
      }
 | 
			
		||||
      lo = lo->Lprev;
 | 
			
		||||
    } else {
 | 
			
		||||
      /* lo->Org is on the left.  We can make CCW triangles from up->Dst. */
 | 
			
		||||
      while( lo->Lnext != up && (EdgeGoesRight( up->Lprev )
 | 
			
		||||
	     || EdgeSign( up->Dst, up->Org, up->Lprev->Org ) >= 0 )) {
 | 
			
		||||
	GLUhalfEdge *tempHalfEdge= __gl_meshConnect( up, up->Lprev );
 | 
			
		||||
	if (tempHalfEdge == NULL) return 0;
 | 
			
		||||
	up = tempHalfEdge->Sym;
 | 
			
		||||
      }
 | 
			
		||||
      up = up->Lnext;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Now lo->Org == up->Dst == the leftmost vertex.  The remaining region
 | 
			
		||||
   * can be tessellated in a fan from this leftmost vertex.
 | 
			
		||||
   */
 | 
			
		||||
  assert( lo->Lnext != up );
 | 
			
		||||
  while( lo->Lnext->Lnext != up ) {
 | 
			
		||||
    GLUhalfEdge *tempHalfEdge= __gl_meshConnect( lo->Lnext, lo );
 | 
			
		||||
    if (tempHalfEdge == NULL) return 0;
 | 
			
		||||
    lo = tempHalfEdge->Sym;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* __gl_meshTessellateInterior( mesh ) tessellates each region of
 | 
			
		||||
 * the mesh which is marked "inside" the polygon.  Each such region
 | 
			
		||||
 * must be monotone.
 | 
			
		||||
 */
 | 
			
		||||
int __gl_meshTessellateInterior( GLUmesh *mesh )
 | 
			
		||||
{
 | 
			
		||||
  GLUface *f, *next;
 | 
			
		||||
 | 
			
		||||
  /*LINTED*/
 | 
			
		||||
  for( f = mesh->fHead.next; f != &mesh->fHead; f = next ) {
 | 
			
		||||
    /* Make sure we don''t try to tessellate the new triangles. */
 | 
			
		||||
    next = f->next;
 | 
			
		||||
    if( f->inside ) {
 | 
			
		||||
      if ( !__gl_meshTessellateMonoRegion( f ) ) return 0;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* __gl_meshDiscardExterior( mesh ) zaps (ie. sets to NULL) all faces
 | 
			
		||||
 * which are not marked "inside" the polygon.  Since further mesh operations
 | 
			
		||||
 * on NULL faces are not allowed, the main purpose is to clean up the
 | 
			
		||||
 * mesh so that exterior loops are not represented in the data structure.
 | 
			
		||||
 */
 | 
			
		||||
void __gl_meshDiscardExterior( GLUmesh *mesh )
 | 
			
		||||
{
 | 
			
		||||
  GLUface *f, *next;
 | 
			
		||||
 | 
			
		||||
  /*LINTED*/
 | 
			
		||||
  for( f = mesh->fHead.next; f != &mesh->fHead; f = next ) {
 | 
			
		||||
    /* Since f will be destroyed, save its next pointer. */
 | 
			
		||||
    next = f->next;
 | 
			
		||||
    if( ! f->inside ) {
 | 
			
		||||
      __gl_meshZapFace( f );
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define MARKED_FOR_DELETION	0x7fffffff
 | 
			
		||||
 | 
			
		||||
/* __gl_meshSetWindingNumber( mesh, value, keepOnlyBoundary ) resets the
 | 
			
		||||
 * winding numbers on all edges so that regions marked "inside" the
 | 
			
		||||
 * polygon have a winding number of "value", and regions outside
 | 
			
		||||
 * have a winding number of 0.
 | 
			
		||||
 *
 | 
			
		||||
 * If keepOnlyBoundary is TRUE, it also deletes all edges which do not
 | 
			
		||||
 * separate an interior region from an exterior one.
 | 
			
		||||
 */
 | 
			
		||||
int __gl_meshSetWindingNumber( GLUmesh *mesh, int value,
 | 
			
		||||
			        GLboolean keepOnlyBoundary )
 | 
			
		||||
{
 | 
			
		||||
  GLUhalfEdge *e, *eNext;
 | 
			
		||||
 | 
			
		||||
  for( e = mesh->eHead.next; e != &mesh->eHead; e = eNext ) {
 | 
			
		||||
    eNext = e->next;
 | 
			
		||||
    if( e->Rface->inside != e->Lface->inside ) {
 | 
			
		||||
 | 
			
		||||
      /* This is a boundary edge (one side is interior, one is exterior). */
 | 
			
		||||
      e->winding = (e->Lface->inside) ? value : -value;
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
      /* Both regions are interior, or both are exterior. */
 | 
			
		||||
      if( ! keepOnlyBoundary ) {
 | 
			
		||||
	e->winding = 0;
 | 
			
		||||
      } else {
 | 
			
		||||
	if ( !__gl_meshDelete( e ) ) return 0;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,71 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 | 
			
		||||
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice including the dates of first publication and
 | 
			
		||||
 * either this permission notice or a reference to
 | 
			
		||||
 * http://oss.sgi.com/projects/FreeB/
 | 
			
		||||
 * shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
			
		||||
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 | 
			
		||||
 * shall not be used in advertising or otherwise to promote the sale, use or
 | 
			
		||||
 * other dealings in this Software without prior written authorization from
 | 
			
		||||
 * Silicon Graphics, Inc.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
** Author: Eric Veach, July 1994.
 | 
			
		||||
**
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __tessmono_h_
 | 
			
		||||
#define __tessmono_h_
 | 
			
		||||
 | 
			
		||||
/* __gl_meshTessellateMonoRegion( face ) tessellates a monotone region
 | 
			
		||||
 * (what else would it do??)  The region must consist of a single
 | 
			
		||||
 * loop of half-edges (see mesh.h) oriented CCW.  "Monotone" in this
 | 
			
		||||
 * case means that any vertical line intersects the interior of the
 | 
			
		||||
 * region in a single interval.  
 | 
			
		||||
 *
 | 
			
		||||
 * Tessellation consists of adding interior edges (actually pairs of
 | 
			
		||||
 * half-edges), to split the region into non-overlapping triangles.
 | 
			
		||||
 *
 | 
			
		||||
 * __gl_meshTessellateInterior( mesh ) tessellates each region of
 | 
			
		||||
 * the mesh which is marked "inside" the polygon.  Each such region
 | 
			
		||||
 * must be monotone.
 | 
			
		||||
 *
 | 
			
		||||
 * __gl_meshDiscardExterior( mesh ) zaps (ie. sets to NULL) all faces
 | 
			
		||||
 * which are not marked "inside" the polygon.  Since further mesh operations
 | 
			
		||||
 * on NULL faces are not allowed, the main purpose is to clean up the
 | 
			
		||||
 * mesh so that exterior loops are not represented in the data structure.
 | 
			
		||||
 *
 | 
			
		||||
 * __gl_meshSetWindingNumber( mesh, value, keepOnlyBoundary ) resets the
 | 
			
		||||
 * winding numbers on all edges so that regions marked "inside" the
 | 
			
		||||
 * polygon have a winding number of "value", and regions outside
 | 
			
		||||
 * have a winding number of 0.
 | 
			
		||||
 *
 | 
			
		||||
 * If keepOnlyBoundary is TRUE, it also deletes all edges which do not
 | 
			
		||||
 * separate an interior region from an exterior one.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
int __gl_meshTessellateMonoRegion( GLUface *face );
 | 
			
		||||
int __gl_meshTessellateInterior( GLUmesh *mesh );
 | 
			
		||||
void __gl_meshDiscardExterior( GLUmesh *mesh );
 | 
			
		||||
int __gl_meshSetWindingNumber( GLUmesh *mesh, int value,
 | 
			
		||||
			        GLboolean keepOnlyBoundary );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -65,12 +65,12 @@ CoglAtlasTexture *
 | 
			
		||||
_cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp,
 | 
			
		||||
                                     gboolean can_convert_in_place);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
_cogl_atlas_texture_add_reorganize_callback (CoglContext *ctx,
 | 
			
		||||
                                             GHookFunc callback,
 | 
			
		||||
                                             void *user_data);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
_cogl_atlas_texture_remove_reorganize_callback (CoglContext *ctx,
 | 
			
		||||
                                                GHookFunc callback,
 | 
			
		||||
                                                void *user_data);
 | 
			
		||||
 
 | 
			
		||||
@@ -74,6 +74,7 @@ typedef struct _CoglAtlasTexture CoglAtlasTexture;
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: a #GType that can be used with the GLib type system.
 | 
			
		||||
 */
 | 
			
		||||
COGL_EXPORT
 | 
			
		||||
GType cogl_atlas_texture_get_gtype (void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -108,7 +109,7 @@ GType cogl_atlas_texture_get_gtype (void);
 | 
			
		||||
 * Since: 1.16
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
CoglAtlasTexture *
 | 
			
		||||
COGL_EXPORT CoglAtlasTexture *
 | 
			
		||||
cogl_atlas_texture_new_with_size (CoglContext *ctx,
 | 
			
		||||
                                  int width,
 | 
			
		||||
                                  int height);
 | 
			
		||||
@@ -146,7 +147,7 @@ cogl_atlas_texture_new_with_size (CoglContext *ctx,
 | 
			
		||||
 * Since: 1.16
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
CoglAtlasTexture *
 | 
			
		||||
COGL_EXPORT CoglAtlasTexture *
 | 
			
		||||
cogl_atlas_texture_new_from_file (CoglContext *ctx,
 | 
			
		||||
                                  const char *filename,
 | 
			
		||||
                                  GError **error);
 | 
			
		||||
@@ -191,7 +192,7 @@ cogl_atlas_texture_new_from_file (CoglContext *ctx,
 | 
			
		||||
 * Since: 1.16
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
CoglAtlasTexture *
 | 
			
		||||
COGL_EXPORT CoglAtlasTexture *
 | 
			
		||||
cogl_atlas_texture_new_from_data (CoglContext *ctx,
 | 
			
		||||
                                  int width,
 | 
			
		||||
                                  int height,
 | 
			
		||||
@@ -231,7 +232,7 @@ cogl_atlas_texture_new_from_data (CoglContext *ctx,
 | 
			
		||||
 * Since: 1.16
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
CoglAtlasTexture *
 | 
			
		||||
COGL_EXPORT CoglAtlasTexture *
 | 
			
		||||
cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -246,7 +247,7 @@ cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp);
 | 
			
		||||
 * Since: 1.16
 | 
			
		||||
 * Stability: Unstable
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
COGL_EXPORT gboolean
 | 
			
		||||
cogl_is_atlas_texture (void *object);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 
 | 
			
		||||
@@ -64,12 +64,12 @@ struct _CoglAtlas
 | 
			
		||||
  GHookList post_reorganize_callbacks;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CoglAtlas *
 | 
			
		||||
COGL_EXPORT CoglAtlas *
 | 
			
		||||
_cogl_atlas_new (CoglPixelFormat texture_format,
 | 
			
		||||
                 CoglAtlasFlags flags,
 | 
			
		||||
                 CoglAtlasUpdatePositionCallback update_position_cb);
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
COGL_EXPORT gboolean
 | 
			
		||||
_cogl_atlas_reserve_space (CoglAtlas             *atlas,
 | 
			
		||||
                           unsigned int           width,
 | 
			
		||||
                           unsigned int           height,
 | 
			
		||||
@@ -87,7 +87,7 @@ _cogl_atlas_copy_rectangle (CoglAtlas *atlas,
 | 
			
		||||
                            int height,
 | 
			
		||||
                            CoglPixelFormat format);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
_cogl_atlas_add_reorganize_callback (CoglAtlas            *atlas,
 | 
			
		||||
                                     GHookFunc             pre_callback,
 | 
			
		||||
                                     GHookFunc             post_callback,
 | 
			
		||||
 
 | 
			
		||||
@@ -64,6 +64,7 @@ G_BEGIN_DECLS
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: a #GType that can be used with the GLib type system.
 | 
			
		||||
 */
 | 
			
		||||
COGL_EXPORT
 | 
			
		||||
GType cogl_attribute_buffer_get_gtype (void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -89,7 +90,7 @@ GType cogl_attribute_buffer_get_gtype (void);
 | 
			
		||||
 *
 | 
			
		||||
 * Stability: Unstable
 | 
			
		||||
 */
 | 
			
		||||
CoglAttributeBuffer *
 | 
			
		||||
COGL_EXPORT CoglAttributeBuffer *
 | 
			
		||||
cogl_attribute_buffer_new_with_size (CoglContext *context,
 | 
			
		||||
                                     size_t bytes);
 | 
			
		||||
 | 
			
		||||
@@ -122,7 +123,7 @@ cogl_attribute_buffer_new_with_size (CoglContext *context,
 | 
			
		||||
 * Since: 1.4
 | 
			
		||||
 * Stability: Unstable
 | 
			
		||||
 */
 | 
			
		||||
CoglAttributeBuffer *
 | 
			
		||||
COGL_EXPORT CoglAttributeBuffer *
 | 
			
		||||
cogl_attribute_buffer_new (CoglContext *context,
 | 
			
		||||
                           size_t bytes,
 | 
			
		||||
                           const void *data);
 | 
			
		||||
@@ -139,7 +140,7 @@ cogl_attribute_buffer_new (CoglContext *context,
 | 
			
		||||
 * Since: 1.4
 | 
			
		||||
 * Stability: Unstable
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
COGL_EXPORT gboolean
 | 
			
		||||
cogl_is_attribute_buffer (void *object);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 
 | 
			
		||||
@@ -63,6 +63,7 @@ G_BEGIN_DECLS
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: a #GType that can be used with the GLib type system.
 | 
			
		||||
 */
 | 
			
		||||
COGL_EXPORT
 | 
			
		||||
GType cogl_attribute_get_gtype (void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -155,7 +156,7 @@ GType cogl_attribute_get_gtype (void);
 | 
			
		||||
 */
 | 
			
		||||
/* XXX: look for a precedent to see if the stride/offset args should
 | 
			
		||||
 * have a different order. */
 | 
			
		||||
CoglAttribute *
 | 
			
		||||
COGL_EXPORT CoglAttribute *
 | 
			
		||||
cogl_attribute_new (CoglAttributeBuffer *attribute_buffer,
 | 
			
		||||
                    const char *name,
 | 
			
		||||
                    size_t stride,
 | 
			
		||||
@@ -183,7 +184,7 @@ cogl_attribute_new (CoglAttributeBuffer *attribute_buffer,
 | 
			
		||||
 * Return value: (transfer full): A newly allocated #CoglAttribute
 | 
			
		||||
 *          representing the given constant @value.
 | 
			
		||||
 */
 | 
			
		||||
CoglAttribute *
 | 
			
		||||
COGL_EXPORT CoglAttribute *
 | 
			
		||||
cogl_attribute_new_const_1f (CoglContext *context,
 | 
			
		||||
                             const char *name,
 | 
			
		||||
                             float value);
 | 
			
		||||
@@ -210,7 +211,7 @@ cogl_attribute_new_const_1f (CoglContext *context,
 | 
			
		||||
 * Return value: (transfer full): A newly allocated #CoglAttribute
 | 
			
		||||
 *          representing the given constant vector.
 | 
			
		||||
 */
 | 
			
		||||
CoglAttribute *
 | 
			
		||||
COGL_EXPORT CoglAttribute *
 | 
			
		||||
cogl_attribute_new_const_2f (CoglContext *context,
 | 
			
		||||
                             const char *name,
 | 
			
		||||
                             float component0,
 | 
			
		||||
@@ -242,7 +243,7 @@ cogl_attribute_new_const_2f (CoglContext *context,
 | 
			
		||||
 * Return value: (transfer full): A newly allocated #CoglAttribute
 | 
			
		||||
 *          representing the given constant vector.
 | 
			
		||||
 */
 | 
			
		||||
CoglAttribute *
 | 
			
		||||
COGL_EXPORT CoglAttribute *
 | 
			
		||||
cogl_attribute_new_const_3f (CoglContext *context,
 | 
			
		||||
                             const char *name,
 | 
			
		||||
                             float component0,
 | 
			
		||||
@@ -277,7 +278,7 @@ cogl_attribute_new_const_3f (CoglContext *context,
 | 
			
		||||
 * Return value: (transfer full): A newly allocated #CoglAttribute
 | 
			
		||||
 *          representing the given constant vector.
 | 
			
		||||
 */
 | 
			
		||||
CoglAttribute *
 | 
			
		||||
COGL_EXPORT CoglAttribute *
 | 
			
		||||
cogl_attribute_new_const_4f (CoglContext *context,
 | 
			
		||||
                             const char *name,
 | 
			
		||||
                             float component0,
 | 
			
		||||
@@ -306,7 +307,7 @@ cogl_attribute_new_const_4f (CoglContext *context,
 | 
			
		||||
 * Return value: (transfer full): A newly allocated #CoglAttribute
 | 
			
		||||
 *          representing the given constant vector.
 | 
			
		||||
 */
 | 
			
		||||
CoglAttribute *
 | 
			
		||||
COGL_EXPORT CoglAttribute *
 | 
			
		||||
cogl_attribute_new_const_2fv (CoglContext *context,
 | 
			
		||||
                              const char *name,
 | 
			
		||||
                              const float *value);
 | 
			
		||||
@@ -335,7 +336,7 @@ cogl_attribute_new_const_2fv (CoglContext *context,
 | 
			
		||||
 * Return value: (transfer full): A newly allocated #CoglAttribute
 | 
			
		||||
 *          representing the given constant vector.
 | 
			
		||||
 */
 | 
			
		||||
CoglAttribute *
 | 
			
		||||
COGL_EXPORT CoglAttribute *
 | 
			
		||||
cogl_attribute_new_const_3fv (CoglContext *context,
 | 
			
		||||
                              const char *name,
 | 
			
		||||
                              const float *value);
 | 
			
		||||
@@ -365,7 +366,7 @@ cogl_attribute_new_const_3fv (CoglContext *context,
 | 
			
		||||
 * Return value: (transfer full): A newly allocated #CoglAttribute
 | 
			
		||||
 *          representing the given constant vector.
 | 
			
		||||
 */
 | 
			
		||||
CoglAttribute *
 | 
			
		||||
COGL_EXPORT CoglAttribute *
 | 
			
		||||
cogl_attribute_new_const_4fv (CoglContext *context,
 | 
			
		||||
                              const char *name,
 | 
			
		||||
                              const float *value);
 | 
			
		||||
@@ -398,7 +399,7 @@ cogl_attribute_new_const_4fv (CoglContext *context,
 | 
			
		||||
 * Return value: (transfer full): A newly allocated #CoglAttribute
 | 
			
		||||
 *          representing the given constant matrix.
 | 
			
		||||
 */
 | 
			
		||||
CoglAttribute *
 | 
			
		||||
COGL_EXPORT CoglAttribute *
 | 
			
		||||
cogl_attribute_new_const_2x2fv (CoglContext *context,
 | 
			
		||||
                                const char *name,
 | 
			
		||||
                                const float *matrix2x2,
 | 
			
		||||
@@ -433,7 +434,7 @@ cogl_attribute_new_const_2x2fv (CoglContext *context,
 | 
			
		||||
 * Return value: (transfer full): A newly allocated #CoglAttribute
 | 
			
		||||
 *          representing the given constant matrix.
 | 
			
		||||
 */
 | 
			
		||||
CoglAttribute *
 | 
			
		||||
COGL_EXPORT CoglAttribute *
 | 
			
		||||
cogl_attribute_new_const_3x3fv (CoglContext *context,
 | 
			
		||||
                                const char *name,
 | 
			
		||||
                                const float *matrix3x3,
 | 
			
		||||
@@ -468,7 +469,7 @@ cogl_attribute_new_const_3x3fv (CoglContext *context,
 | 
			
		||||
 * Return value: (transfer full): A newly allocated #CoglAttribute
 | 
			
		||||
 *          representing the given constant matrix.
 | 
			
		||||
 */
 | 
			
		||||
CoglAttribute *
 | 
			
		||||
COGL_EXPORT CoglAttribute *
 | 
			
		||||
cogl_attribute_new_const_4x4fv (CoglContext *context,
 | 
			
		||||
                                const char *name,
 | 
			
		||||
                                const float *matrix4x4,
 | 
			
		||||
@@ -492,7 +493,7 @@ cogl_attribute_new_const_4x4fv (CoglContext *context,
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 * Since: 1.10
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_attribute_set_normalized (CoglAttribute *attribute,
 | 
			
		||||
                               gboolean normalized);
 | 
			
		||||
 | 
			
		||||
@@ -506,7 +507,7 @@ cogl_attribute_set_normalized (CoglAttribute *attribute,
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 * Since: 1.10
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
COGL_EXPORT gboolean
 | 
			
		||||
cogl_attribute_get_normalized (CoglAttribute *attribute);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -519,7 +520,7 @@ cogl_attribute_get_normalized (CoglAttribute *attribute);
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 * Since: 1.10
 | 
			
		||||
 */
 | 
			
		||||
CoglAttributeBuffer *
 | 
			
		||||
COGL_EXPORT CoglAttributeBuffer *
 | 
			
		||||
cogl_attribute_get_buffer (CoglAttribute *attribute);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -532,7 +533,7 @@ cogl_attribute_get_buffer (CoglAttribute *attribute);
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 * Since: 1.10
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_attribute_set_buffer (CoglAttribute *attribute,
 | 
			
		||||
                           CoglAttributeBuffer *attribute_buffer);
 | 
			
		||||
 | 
			
		||||
@@ -545,7 +546,7 @@ cogl_attribute_set_buffer (CoglAttribute *attribute,
 | 
			
		||||
 * Return value: %TRUE if the @object references a #CoglAttribute,
 | 
			
		||||
 *   %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
COGL_EXPORT gboolean
 | 
			
		||||
cogl_is_attribute (void *object);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 
 | 
			
		||||
@@ -54,6 +54,7 @@ G_BEGIN_DECLS
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: a #GType that can be used with the GLib type system.
 | 
			
		||||
 */
 | 
			
		||||
COGL_EXPORT
 | 
			
		||||
GType cogl_bitmap_get_gtype (void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -80,7 +81,7 @@ GType cogl_bitmap_get_gtype (void);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
CoglBitmap *
 | 
			
		||||
COGL_EXPORT CoglBitmap *
 | 
			
		||||
cogl_bitmap_new_from_file (const char *filename,
 | 
			
		||||
                           GError **error);
 | 
			
		||||
 | 
			
		||||
@@ -103,7 +104,7 @@ cogl_bitmap_new_from_file (const char *filename,
 | 
			
		||||
 * Since: 1.8
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
CoglBitmap *
 | 
			
		||||
COGL_EXPORT CoglBitmap *
 | 
			
		||||
cogl_bitmap_new_from_buffer (CoglBuffer *buffer,
 | 
			
		||||
                             CoglPixelFormat format,
 | 
			
		||||
                             int width,
 | 
			
		||||
@@ -140,7 +141,7 @@ cogl_bitmap_new_from_buffer (CoglBuffer *buffer,
 | 
			
		||||
 * Since: 1.10
 | 
			
		||||
 * Stability: Unstable
 | 
			
		||||
 */
 | 
			
		||||
CoglBitmap *
 | 
			
		||||
COGL_EXPORT CoglBitmap *
 | 
			
		||||
cogl_bitmap_new_with_size (CoglContext *context,
 | 
			
		||||
                           unsigned int width,
 | 
			
		||||
                           unsigned int height,
 | 
			
		||||
@@ -166,7 +167,7 @@ cogl_bitmap_new_with_size (CoglContext *context,
 | 
			
		||||
 * Since: 1.10
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
CoglBitmap *
 | 
			
		||||
COGL_EXPORT CoglBitmap *
 | 
			
		||||
cogl_bitmap_new_for_data (CoglContext *context,
 | 
			
		||||
                          int width,
 | 
			
		||||
                          int height,
 | 
			
		||||
@@ -182,7 +183,7 @@ cogl_bitmap_new_for_data (CoglContext *context,
 | 
			
		||||
 * Since: 1.10
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
CoglPixelFormat
 | 
			
		||||
COGL_EXPORT CoglPixelFormat
 | 
			
		||||
cogl_bitmap_get_format (CoglBitmap *bitmap);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -193,7 +194,7 @@ cogl_bitmap_get_format (CoglBitmap *bitmap);
 | 
			
		||||
 * Since: 1.10
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
COGL_EXPORT int
 | 
			
		||||
cogl_bitmap_get_width (CoglBitmap *bitmap);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -204,7 +205,7 @@ cogl_bitmap_get_width (CoglBitmap *bitmap);
 | 
			
		||||
 * Since: 1.10
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
COGL_EXPORT int
 | 
			
		||||
cogl_bitmap_get_height (CoglBitmap *bitmap);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -217,7 +218,7 @@ cogl_bitmap_get_height (CoglBitmap *bitmap);
 | 
			
		||||
 * Since: 1.10
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
COGL_EXPORT int
 | 
			
		||||
cogl_bitmap_get_rowstride (CoglBitmap *bitmap);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -231,7 +232,7 @@ cogl_bitmap_get_rowstride (CoglBitmap *bitmap);
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 * Since: 1.10
 | 
			
		||||
 */
 | 
			
		||||
CoglPixelBuffer *
 | 
			
		||||
COGL_EXPORT CoglPixelBuffer *
 | 
			
		||||
cogl_bitmap_get_buffer (CoglBitmap *bitmap);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -247,7 +248,7 @@ cogl_bitmap_get_buffer (CoglBitmap *bitmap);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
COGL_EXPORT gboolean
 | 
			
		||||
cogl_bitmap_get_size_from_file (const char *filename,
 | 
			
		||||
                                int *width,
 | 
			
		||||
                                int *height);
 | 
			
		||||
@@ -263,7 +264,7 @@ cogl_bitmap_get_size_from_file (const char *filename,
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
COGL_EXPORT gboolean
 | 
			
		||||
cogl_is_bitmap (void *object);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -297,6 +298,7 @@ typedef enum
 | 
			
		||||
  COGL_BITMAP_ERROR_CORRUPT_IMAGE
 | 
			
		||||
} CoglBitmapError;
 | 
			
		||||
 | 
			
		||||
COGL_EXPORT
 | 
			
		||||
uint32_t cogl_bitmap_error_quark (void);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 
 | 
			
		||||
@@ -168,10 +168,10 @@ void *
 | 
			
		||||
_cogl_buffer_map_range_for_fill_or_fallback (CoglBuffer *buffer,
 | 
			
		||||
                                             size_t offset,
 | 
			
		||||
                                             size_t size);
 | 
			
		||||
void *
 | 
			
		||||
COGL_EXPORT void *
 | 
			
		||||
_cogl_buffer_map_for_fill_or_fallback (CoglBuffer *buffer);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
_cogl_buffer_unmap_for_fill_or_fallback (CoglBuffer *buffer);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 
 | 
			
		||||
@@ -107,7 +107,7 @@ _cogl_buffer_error_domain (void);
 | 
			
		||||
 * Since: 1.2
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
COGL_EXPORT gboolean
 | 
			
		||||
cogl_is_buffer (void *object);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -121,7 +121,7 @@ cogl_is_buffer (void *object);
 | 
			
		||||
 * Since: 1.2
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
unsigned int
 | 
			
		||||
COGL_EXPORT unsigned int
 | 
			
		||||
cogl_buffer_get_size (CoglBuffer *buffer);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -155,7 +155,7 @@ typedef enum /*< prefix=COGL_BUFFER_UPDATE_HINT >*/
 | 
			
		||||
 * Since: 1.2
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_buffer_set_update_hint (CoglBuffer          *buffer,
 | 
			
		||||
                             CoglBufferUpdateHint hint);
 | 
			
		||||
 | 
			
		||||
@@ -170,7 +170,7 @@ cogl_buffer_set_update_hint (CoglBuffer          *buffer,
 | 
			
		||||
 * Since: 1.2
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
CoglBufferUpdateHint
 | 
			
		||||
COGL_EXPORT CoglBufferUpdateHint
 | 
			
		||||
cogl_buffer_get_update_hint (CoglBuffer *buffer);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -244,7 +244,7 @@ typedef enum /*< prefix=COGL_BUFFER_MAP_HINT >*/
 | 
			
		||||
 * Since: 1.2
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
void *
 | 
			
		||||
COGL_EXPORT void *
 | 
			
		||||
cogl_buffer_map (CoglBuffer *buffer,
 | 
			
		||||
                 CoglBufferAccess access,
 | 
			
		||||
                 CoglBufferMapHint hints);
 | 
			
		||||
@@ -281,7 +281,7 @@ cogl_buffer_map (CoglBuffer *buffer,
 | 
			
		||||
 * Since: 2.0
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
void *
 | 
			
		||||
COGL_EXPORT void *
 | 
			
		||||
cogl_buffer_map_range (CoglBuffer *buffer,
 | 
			
		||||
                       size_t offset,
 | 
			
		||||
                       size_t size,
 | 
			
		||||
@@ -298,7 +298,7 @@ cogl_buffer_map_range (CoglBuffer *buffer,
 | 
			
		||||
 * Since: 1.2
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_buffer_unmap (CoglBuffer *buffer);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -317,7 +317,7 @@ cogl_buffer_unmap (CoglBuffer *buffer);
 | 
			
		||||
 * Since: 1.2
 | 
			
		||||
 * Stability: unstable
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
COGL_EXPORT gboolean
 | 
			
		||||
cogl_buffer_set_data (CoglBuffer *buffer,
 | 
			
		||||
                      size_t offset,
 | 
			
		||||
                      const void *data,
 | 
			
		||||
 
 | 
			
		||||
@@ -178,7 +178,7 @@ _cogl_clip_stack_push_window_rectangle (CoglClipStack *stack,
 | 
			
		||||
                                        int width,
 | 
			
		||||
                                        int height);
 | 
			
		||||
 | 
			
		||||
CoglClipStack *
 | 
			
		||||
COGL_EXPORT CoglClipStack *
 | 
			
		||||
_cogl_clip_stack_push_rectangle (CoglClipStack *stack,
 | 
			
		||||
                                 float x_1,
 | 
			
		||||
                                 float y_1,
 | 
			
		||||
@@ -188,7 +188,7 @@ _cogl_clip_stack_push_rectangle (CoglClipStack *stack,
 | 
			
		||||
                                 CoglMatrixEntry *projection_entry,
 | 
			
		||||
                                 const float *viewport);
 | 
			
		||||
 | 
			
		||||
CoglClipStack *
 | 
			
		||||
COGL_EXPORT CoglClipStack *
 | 
			
		||||
_cogl_clip_stack_push_primitive (CoglClipStack *stack,
 | 
			
		||||
                                 CoglPrimitive *primitive,
 | 
			
		||||
                                 float bounds_x1,
 | 
			
		||||
 
 | 
			
		||||
@@ -65,7 +65,7 @@ typedef struct _CoglClosure
 | 
			
		||||
 * Removes the given closure from the callback list it is connected to
 | 
			
		||||
 * and destroys it. If the closure was created with a destroy function
 | 
			
		||||
 * then it will be invoked. */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
_cogl_closure_disconnect (CoglClosure *closure);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 
 | 
			
		||||
@@ -57,6 +57,7 @@ G_BEGIN_DECLS
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: a #GType that can be used with the GLib type system.
 | 
			
		||||
 */
 | 
			
		||||
COGL_EXPORT
 | 
			
		||||
GType cogl_color_get_gtype (void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -69,7 +70,7 @@ GType cogl_color_get_gtype (void);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
CoglColor *
 | 
			
		||||
COGL_EXPORT CoglColor *
 | 
			
		||||
cogl_color_new (void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -83,7 +84,7 @@ cogl_color_new (void);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
CoglColor *
 | 
			
		||||
COGL_EXPORT CoglColor *
 | 
			
		||||
cogl_color_copy (const CoglColor *color);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -94,7 +95,7 @@ cogl_color_copy (const CoglColor *color);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_color_free (CoglColor *color);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -109,7 +110,7 @@ cogl_color_free (CoglColor *color);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_color_init_from_4ub (CoglColor *color,
 | 
			
		||||
                          uint8_t red,
 | 
			
		||||
                          uint8_t green,
 | 
			
		||||
@@ -128,7 +129,7 @@ cogl_color_init_from_4ub (CoglColor *color,
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_color_init_from_4f (CoglColor *color,
 | 
			
		||||
                         float red,
 | 
			
		||||
                         float green,
 | 
			
		||||
@@ -144,7 +145,7 @@ cogl_color_init_from_4f (CoglColor *color,
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_color_init_from_4fv (CoglColor *color,
 | 
			
		||||
                          const float *color_array);
 | 
			
		||||
 | 
			
		||||
@@ -159,7 +160,7 @@ cogl_color_init_from_4fv (CoglColor *color,
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
unsigned char
 | 
			
		||||
COGL_EXPORT unsigned char
 | 
			
		||||
cogl_color_get_red_byte (const CoglColor *color);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -173,7 +174,7 @@ cogl_color_get_red_byte (const CoglColor *color);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
unsigned char
 | 
			
		||||
COGL_EXPORT unsigned char
 | 
			
		||||
cogl_color_get_green_byte (const CoglColor *color);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -187,7 +188,7 @@ cogl_color_get_green_byte (const CoglColor *color);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
unsigned char
 | 
			
		||||
COGL_EXPORT unsigned char
 | 
			
		||||
cogl_color_get_blue_byte (const CoglColor *color);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -201,7 +202,7 @@ cogl_color_get_blue_byte (const CoglColor *color);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
unsigned char
 | 
			
		||||
COGL_EXPORT unsigned char
 | 
			
		||||
cogl_color_get_alpha_byte (const CoglColor *color);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -215,7 +216,7 @@ cogl_color_get_alpha_byte (const CoglColor *color);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
float
 | 
			
		||||
COGL_EXPORT float
 | 
			
		||||
cogl_color_get_red_float (const CoglColor *color);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -229,7 +230,7 @@ cogl_color_get_red_float (const CoglColor *color);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
float
 | 
			
		||||
COGL_EXPORT float
 | 
			
		||||
cogl_color_get_green_float (const CoglColor *color);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -243,7 +244,7 @@ cogl_color_get_green_float (const CoglColor *color);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
float
 | 
			
		||||
COGL_EXPORT float
 | 
			
		||||
cogl_color_get_blue_float (const CoglColor *color);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -257,7 +258,7 @@ cogl_color_get_blue_float (const CoglColor *color);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
float
 | 
			
		||||
COGL_EXPORT float
 | 
			
		||||
cogl_color_get_alpha_float (const CoglColor *color);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -271,7 +272,7 @@ cogl_color_get_alpha_float (const CoglColor *color);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
float
 | 
			
		||||
COGL_EXPORT float
 | 
			
		||||
cogl_color_get_red (const CoglColor *color);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -285,7 +286,7 @@ cogl_color_get_red (const CoglColor *color);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
float
 | 
			
		||||
COGL_EXPORT float
 | 
			
		||||
cogl_color_get_green (const CoglColor *color);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -299,7 +300,7 @@ cogl_color_get_green (const CoglColor *color);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
float
 | 
			
		||||
COGL_EXPORT float
 | 
			
		||||
cogl_color_get_blue (const CoglColor *color);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -313,7 +314,7 @@ cogl_color_get_blue (const CoglColor *color);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
float
 | 
			
		||||
COGL_EXPORT float
 | 
			
		||||
cogl_color_get_alpha (const CoglColor *color);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -325,7 +326,7 @@ cogl_color_get_alpha (const CoglColor *color);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_color_set_red_byte (CoglColor     *color,
 | 
			
		||||
                         unsigned char  red);
 | 
			
		||||
 | 
			
		||||
@@ -338,7 +339,7 @@ cogl_color_set_red_byte (CoglColor     *color,
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_color_set_green_byte (CoglColor     *color,
 | 
			
		||||
                           unsigned char  green);
 | 
			
		||||
 | 
			
		||||
@@ -351,7 +352,7 @@ cogl_color_set_green_byte (CoglColor     *color,
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_color_set_blue_byte (CoglColor     *color,
 | 
			
		||||
                          unsigned char  blue);
 | 
			
		||||
 | 
			
		||||
@@ -364,7 +365,7 @@ cogl_color_set_blue_byte (CoglColor     *color,
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_color_set_alpha_byte (CoglColor     *color,
 | 
			
		||||
                           unsigned char  alpha);
 | 
			
		||||
 | 
			
		||||
@@ -377,7 +378,7 @@ cogl_color_set_alpha_byte (CoglColor     *color,
 | 
			
		||||
 *
 | 
			
		||||
 * since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_color_set_red_float (CoglColor *color,
 | 
			
		||||
                          float      red);
 | 
			
		||||
 | 
			
		||||
@@ -390,7 +391,7 @@ cogl_color_set_red_float (CoglColor *color,
 | 
			
		||||
 *
 | 
			
		||||
 * since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_color_set_green_float (CoglColor *color,
 | 
			
		||||
                            float      green);
 | 
			
		||||
 | 
			
		||||
@@ -403,7 +404,7 @@ cogl_color_set_green_float (CoglColor *color,
 | 
			
		||||
 *
 | 
			
		||||
 * since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_color_set_blue_float (CoglColor *color,
 | 
			
		||||
                           float      blue);
 | 
			
		||||
 | 
			
		||||
@@ -416,7 +417,7 @@ cogl_color_set_blue_float (CoglColor *color,
 | 
			
		||||
 *
 | 
			
		||||
 * since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_color_set_alpha_float (CoglColor *color,
 | 
			
		||||
                            float      alpha);
 | 
			
		||||
 | 
			
		||||
@@ -429,7 +430,7 @@ cogl_color_set_alpha_float (CoglColor *color,
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_color_set_red (CoglColor *color,
 | 
			
		||||
                    float      red);
 | 
			
		||||
 | 
			
		||||
@@ -442,7 +443,7 @@ cogl_color_set_red (CoglColor *color,
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_color_set_green (CoglColor *color,
 | 
			
		||||
                      float green);
 | 
			
		||||
 | 
			
		||||
@@ -455,7 +456,7 @@ cogl_color_set_green (CoglColor *color,
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_color_set_blue (CoglColor *color,
 | 
			
		||||
                     float blue);
 | 
			
		||||
 | 
			
		||||
@@ -468,7 +469,7 @@ cogl_color_set_blue (CoglColor *color,
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_color_set_alpha (CoglColor *color,
 | 
			
		||||
                      float alpha);
 | 
			
		||||
 | 
			
		||||
@@ -482,7 +483,7 @@ cogl_color_set_alpha (CoglColor *color,
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_color_premultiply (CoglColor *color);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -495,7 +496,7 @@ cogl_color_premultiply (CoglColor *color);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_color_unpremultiply (CoglColor *color);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -512,7 +513,7 @@ cogl_color_unpremultiply (CoglColor *color);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
COGL_EXPORT gboolean
 | 
			
		||||
cogl_color_equal (const void *v1, const void *v2);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -529,7 +530,7 @@ cogl_color_equal (const void *v1, const void *v2);
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.16
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_color_to_hsl (const CoglColor *color,
 | 
			
		||||
                   float           *hue,
 | 
			
		||||
                   float           *saturation,
 | 
			
		||||
@@ -547,7 +548,7 @@ cogl_color_to_hsl (const CoglColor *color,
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.16
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_color_init_from_hsl (CoglColor *color,
 | 
			
		||||
                          float      hue,
 | 
			
		||||
                          float      saturation,
 | 
			
		||||
 
 | 
			
		||||
@@ -52,7 +52,6 @@
 | 
			
		||||
#include "cogl-onscreen-private.h"
 | 
			
		||||
#include "cogl-fence-private.h"
 | 
			
		||||
#include "cogl-poll-private.h"
 | 
			
		||||
#include "cogl-path/cogl-path-types.h"
 | 
			
		||||
#include "cogl-private.h"
 | 
			
		||||
#include "winsys/cogl-winsys-private.h"
 | 
			
		||||
 | 
			
		||||
@@ -125,11 +124,6 @@ struct _CoglContext
 | 
			
		||||
 | 
			
		||||
  CoglMatrixEntry identity_entry;
 | 
			
		||||
 | 
			
		||||
  /* A cache of the last (immutable) matrix stack entries that were
 | 
			
		||||
   * flushed to the GL matrix builtins */
 | 
			
		||||
  CoglMatrixEntryCache builtin_flushed_projection;
 | 
			
		||||
  CoglMatrixEntryCache builtin_flushed_modelview;
 | 
			
		||||
 | 
			
		||||
  GArray           *texture_units;
 | 
			
		||||
  int               active_texture_unit;
 | 
			
		||||
 | 
			
		||||
@@ -153,8 +147,6 @@ struct _CoglContext
 | 
			
		||||
  GArray           *journal_flush_attributes_array;
 | 
			
		||||
  GArray           *journal_clip_bounds;
 | 
			
		||||
 | 
			
		||||
  GArray           *polygon_vertices;
 | 
			
		||||
 | 
			
		||||
  /* Some simple caching, to minimize state changes... */
 | 
			
		||||
  CoglPipeline     *current_pipeline;
 | 
			
		||||
  unsigned long     current_pipeline_changes_since_flush;
 | 
			
		||||
@@ -196,20 +188,12 @@ struct _CoglContext
 | 
			
		||||
  gboolean was_bound_to_onscreen;
 | 
			
		||||
 | 
			
		||||
  /* Primitives */
 | 
			
		||||
  CoglPath         *current_path;
 | 
			
		||||
  CoglPipeline     *stencil_pipeline;
 | 
			
		||||
 | 
			
		||||
  /* Pre-generated VBOs containing indices to generate GL_TRIANGLES
 | 
			
		||||
     out of a vertex array of quads */
 | 
			
		||||
  CoglIndices      *quad_buffer_indices_byte;
 | 
			
		||||
  unsigned int      quad_buffer_indices_len;
 | 
			
		||||
  CoglIndices      *quad_buffer_indices;
 | 
			
		||||
 | 
			
		||||
  CoglIndices      *rectangle_byte_indices;
 | 
			
		||||
  CoglIndices      *rectangle_short_indices;
 | 
			
		||||
  int               rectangle_short_indices_len;
 | 
			
		||||
 | 
			
		||||
  CoglPipeline     *texture_download_pipeline;
 | 
			
		||||
  CoglPipeline     *blit_texture_pipeline;
 | 
			
		||||
 | 
			
		||||
  GSList           *atlases;
 | 
			
		||||
@@ -300,7 +284,7 @@ struct _CoglContext
 | 
			
		||||
#undef COGL_EXT_END
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CoglContext *
 | 
			
		||||
COGL_EXPORT CoglContext *
 | 
			
		||||
_cogl_context_get_default (void);
 | 
			
		||||
 | 
			
		||||
const CoglWinsysVtable *
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user